From b5bd4fd7377753781794caa32451789d3d7fc9da Mon Sep 17 00:00:00 2001 From: dctouch Date: Sat, 11 Apr 2026 14:56:14 +0300 Subject: [PATCH] =?UTF-8?q?=D0=93=D0=9B=D0=9E=D0=91=D0=90=D0=9B=D0=AC?= =?UTF-8?q?=D0=9D=D0=AB=D0=99=20=D0=A0=D0=95=D0=A4=D0=90=D0=9A=D0=A2=D0=9E?= =?UTF-8?q?=D0=A0=D0=98=D0=9D=D0=93=20=D0=90=D0=A0=D0=A5=D0=98=D0=A2=D0=95?= =?UTF-8?q?=D0=9A=D0=A2=D0=A3=D0=A0=D0=AB=20-=20=D0=A0=D0=B5=D1=84=D0=B0?= =?UTF-8?q?=D0=BA=D1=82=D0=BE=D1=80=D0=B8=D0=BD=D0=B3=20=D1=8D=D1=82=D0=B0?= =?UTF-8?q?=D0=BF=D0=BE=D0=B2=202.2=20-=20=D0=A3=D1=81=D0=B8=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=D0=B0=20=D0=BE=D1=80=D0=BA=D0=B5=D1=81=D1=82=D1=80=D0=B0?= =?UTF-8?q?=D1=86=D0=B8=D1=8E=20=D0=B2=20deep/address=20=D0=B3=D0=B5=D0=B9?= =?UTF-8?q?=D1=82=D0=B5=20=D0=B8=20follow-up=20binding=20=D0=B2=20assistan?= =?UTF-8?q?tService.ts.=20=D0=9F=D0=BE=D1=87=D0=B8=D0=BD=D0=B5=D0=BD=20?= =?UTF-8?q?=D0=BA=D0=B5=D0=B9=D1=81=20UTF-8=20follow-up=20refinement=20(?= =?UTF-8?q?=D1=82=D0=B5=D0=BF=D0=B5=D1=80=D1=8C=20followup=5Fstate=5Fusage?= =?UTF-8?q?.applied=3Dtrue=20=D0=B2=20=D0=BD=D1=83=D0=B6=D0=BD=D0=BE=D0=BC?= =?UTF-8?q?=20=D1=81=D1=86=D0=B5=D0=BD=D0=B0=D1=80=D0=B8=D0=B8).=20=20?= =?UTF-8?q?=D0=A3=D0=B1=D1=80=D0=B0=D0=BD=D1=8B=20=D1=80=D0=B5=D0=B3=D1=80?= =?UTF-8?q?=D0=B5=D1=81=D1=81=D0=B8=D0=B8=20=D0=BF=D0=BE=20assistantLiving?= =?UTF-8?q?Router=20=D0=B8=20stage3=20lifecycle=20probe.=20=D0=9A=D0=BE?= =?UTF-8?q?=D1=80=D1=80=D0=B5=D0=BA=D1=82=D0=BD=D0=BE=D0=B5=20=D0=BF=D0=BE?= =?UTF-8?q?=D0=B2=D0=B5=D0=B4=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=B4=D0=BB=D1=8F?= =?UTF-8?q?=20llm=20canonical=20candidate=20(=D1=87=D1=82=D0=BE=D0=B1?= =?UTF-8?q?=D1=8B=20=D0=BD=D0=B5=20=D1=83=D0=B5=D0=B7=D0=B6=D0=B0=D0=BB?= =?UTF-8?q?=D0=BE=20=D0=B2=20clarification=5Frequired=20=D1=82=D0=B0=D0=BC?= =?UTF-8?q?,=20=D0=B3=D0=B4=D0=B5=20=D0=B4=D0=BE=D0=BB=D0=B6=D0=B5=D0=BD?= =?UTF-8?q?=20=D0=B1=D1=8B=D1=82=D1=8C=20address=20factual).?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/TECH/1CLLMARCH-FACT.md | 254 +++++++++++++++++- ...tantDeepTurnAnalysisAttemptInputBuilder.js | 19 +- ...tantDeepTurnNormalizationRuntimeAdapter.js | 9 +- .../services/assistantDeepTurnPackaging.js | 11 +- ...assistantDeepTurnResponseRuntimeAdapter.js | 58 ++-- ...ssistantDeepTurnRetrievalRuntimeAdapter.js | 20 +- .../assistantTurnRuntimeDepsAdapter.js | 12 +- ...stantAddressOrchestrationRuntimeAdapter.ts | 2 + .../assistantDebugPayloadAssembler.ts | 87 +++--- ...tantDeepTurnAnalysisAttemptInputBuilder.ts | 28 +- .../assistantDeepTurnAttemptInputBuilder.ts | 5 +- ...istantDeepTurnCompositionRuntimeAdapter.ts | 8 +- .../assistantDeepTurnContextRuntimeAdapter.ts | 10 +- ...assistantDeepTurnFinalizeRuntimeAdapter.ts | 3 +- .../services/assistantDeepTurnInputBuilder.ts | 77 +++--- ...tantDeepTurnNormalizationRuntimeAdapter.ts | 15 +- .../services/assistantDeepTurnPackaging.ts | 101 ++++--- ...ssistantDeepTurnPackagingRuntimeAdapter.ts | 65 ++--- .../assistantDeepTurnPlanRuntimeAdapter.ts | 23 +- .../assistantDeepTurnPrePackagingContext.ts | 9 +- ...assistantDeepTurnResponseRuntimeAdapter.ts | 130 ++++----- ...ssistantDeepTurnRetrievalRuntimeAdapter.ts | 62 ++++- .../assistantEvidenceBundleAssembler.ts | 3 +- .../services/assistantMessageLogAssembler.ts | 81 ++++-- .../assistantOrchestrationContracts.ts | 3 +- .../src/services/assistantQueryPlanning.ts | 3 +- .../src/services/assistantRuntimeGuards.ts | 64 ++++- .../backend/src/services/assistantService.ts | 185 ++++++++++++- .../assistantTurnRuntimeDepsAdapter.ts | 12 +- llm_normalizer/backend/src/types/assistant.ts | 50 +++- llm_normalizer/backend/src/utils/log.ts | 3 + .../tests/assistantLivingRouter.test.ts | 36 +++ .../assistantTurnRuntimeDepsAdapter.test.ts | 85 ++++++ .../backend/vitest-full-report.json | 1 + .../eval_cases/eval-5S6BYeWJWv.report.json | 112 ++++++++ .../eval_cases/eval-D1gt1OyBqh.report.json | 112 ++++++++ .../eval_cases/eval-EYDYh4k78m.report.json | 137 ++++++++++ .../eval_cases/eval-NeqPDTflc7.report.json | 112 ++++++++ .../eval_cases/eval-OSNnoiu9KQ.report.json | 137 ++++++++++ .../eval_cases/eval-RVeDpGREWm.report.json | 112 ++++++++ .../eval_cases/eval-hhXvDmFzGJ.report.json | 137 ++++++++++ .../eval_cases/eval-kBTYkPR4wq.report.json | 112 ++++++++ .../eval_cases/eval-nL2h6Z0kKG.report.json | 112 ++++++++ .../eval_cases/eval-qYzl2S0IV9.report.json | 112 ++++++++ .../eval_cases/eval-wWlVBoabZW.report.json | 112 ++++++++ tmp_llm_gate_log.txt | Bin 0 -> 37422 bytes 46 files changed, 2471 insertions(+), 370 deletions(-) create mode 100644 llm_normalizer/backend/vitest-full-report.json create mode 100644 llm_normalizer/data/eval_cases/eval-5S6BYeWJWv.report.json create mode 100644 llm_normalizer/data/eval_cases/eval-D1gt1OyBqh.report.json create mode 100644 llm_normalizer/data/eval_cases/eval-EYDYh4k78m.report.json create mode 100644 llm_normalizer/data/eval_cases/eval-NeqPDTflc7.report.json create mode 100644 llm_normalizer/data/eval_cases/eval-OSNnoiu9KQ.report.json create mode 100644 llm_normalizer/data/eval_cases/eval-RVeDpGREWm.report.json create mode 100644 llm_normalizer/data/eval_cases/eval-hhXvDmFzGJ.report.json create mode 100644 llm_normalizer/data/eval_cases/eval-kBTYkPR4wq.report.json create mode 100644 llm_normalizer/data/eval_cases/eval-nL2h6Z0kKG.report.json create mode 100644 llm_normalizer/data/eval_cases/eval-qYzl2S0IV9.report.json create mode 100644 llm_normalizer/data/eval_cases/eval-wWlVBoabZW.report.json create mode 100644 tmp_llm_gate_log.txt diff --git a/docs/TECH/1CLLMARCH-FACT.md b/docs/TECH/1CLLMARCH-FACT.md index 6a9fa81..c26c298 100644 --- a/docs/TECH/1CLLMARCH-FACT.md +++ b/docs/TECH/1CLLMARCH-FACT.md @@ -1,6 +1,6 @@ # 1CLLMARCH Fact Check And Stabilization Plan -Updated at: 2026-04-10 +Updated at: 2026-04-11 Source baseline: `docs/TECH/1CLLMARCH.md` ## 1. Purpose @@ -2096,7 +2096,236 @@ Validation: - `assistantDeepTurnAnalysisRuntimeAdapter.test.ts` - `assistantDeepTurnAnalysisAttemptRuntimeAdapter.test.ts` -Status: **In progress (Phase 2.1 + 2.2 + 2.3 + 2.4 + 2.5 + 2.6 + 2.7 + 2.8 + 2.9 + 2.10 + 2.11 + 2.12 + 2.13 + 2.14 + 2.15 + 2.16 + 2.17 + 2.18 + 2.19 + 2.20 + 2.21 + 2.22 + 2.23 + 2.24 + 2.25 + 2.26 + 2.27 + 2.28 + 2.29 + 2.30 + 2.31 + 2.32 + 2.33 + 2.34 + 2.35 + 2.36 + 2.37 + 2.38 + 2.39 + 2.40 + 2.41 + 2.42 + 2.43 + 2.44 + 2.45 + 2.46 + 2.47 + 2.48 + 2.49 + 2.50 + 2.51 + 2.52 + 2.53 + 2.54 + 2.55 + 2.56 + 2.57 + 2.58 + 2.59 + 2.60 + 2.61 + 2.62 + 2.63 + 2.64 + 2.65 + 2.66 + 2.67 + 2.68 + 2.69 + 2.70 + 2.71 + 2.72 + 2.73 + 2.74 + 2.75 + 2.76 + 2.77 + 2.78 + 2.79 + 2.80 + 2.81 + 2.82 + 2.83 + 2.84 + 2.85 + 2.86 + 2.87 + 2.88 + 2.89 + 2.90 + 2.91 + 2.92 + 2.93 + 2.94 + 2.95 + 2.96 + 2.97 + 2.98 + 2.99 + 2.100 + 2.101 + 2.102 + 2.103 + 2.104 + 2.105 + 2.106 + 2.107 + 2.108 + 2.109 + 2.110 + 2.111 + 2.112 completed)** +Implemented in current pass (Phase 2.113 + 2.114 + 2.115 + 2.116): +1. Tightened temporal/polarity guard typing in deep plan runtime: + - `assistantDeepTurnPlanRuntimeAdapter.ts` + - `temporalGuard` now typed to `TemporalGuardAudit`; + - `domainPolarityGuardInitial` now typed to `DomainPolarityGuardAudit`. +2. Preserved behavior: + - no runtime logic changes; type alignment only. + +Validation: +1. `npm run build` passed. +2. Targeted deep plan pack passed: + - `assistantDeepTurnPlanRuntimeAdapter.test.ts` + - `assistantDeepTurnAnalysisAttemptRuntimeAdapter.test.ts` + +Implemented in current pass (Phase 2.117 + 2.118 + 2.119 + 2.120): +1. Tightened audit typing along deep response/packaging chain: + - `assistantDebugPayloadAssembler.ts` + - `assistantMessageLogAssembler.ts` + - `assistantDeepTurnPackaging.ts` + - `assistantDeepTurnPackagingRuntimeAdapter.ts` + - `assistantDeepTurnInputBuilder.ts` + - `assistantDeepTurnResponseRuntimeAdapter.ts` + - audit contracts now use concrete types: + - `TemporalGuardAudit`, `DomainPolarityGuardAudit`, `ClaimBoundAnchorAudit`, + `TargetedEvidenceAcquisitionAudit`, `EvidenceAdmissibilityAudit`, + `GroundedAnswerEligibilityAudit`, + `RbpLiveRouteAuditDebug | null`, `FaLiveRouteAuditDebug | null`. +2. Preserved behavior: + - no runtime logic changes; type alignment only. + +Validation: +1. `npm run build` passed. +2. Targeted deep response/packaging pack passed: + - `assistantDeepTurnResponseRuntimeAdapter.test.ts` + - `assistantDeepTurnResponseAttemptRuntimeAdapter.test.ts` + - `assistantDeepTurnPackagingRuntimeAdapter.test.ts` + - `assistantDeepTurnPackaging.test.ts` + +Implemented in current pass (Phase 2.121 + 2.122 + 2.123 + 2.124): +1. Tightened retrieval call/raw types across deep response chain: + - `assistantDeepTurnRetrievalRuntimeAdapter.ts` + - `assistantDeepTurnResponseRuntimeAdapter.ts` + - `assistantDeepTurnPackaging.ts` + - `assistantDeepTurnPackagingRuntimeAdapter.ts` + - `assistantDeepTurnInputBuilder.ts` + - `assistantMessageLogAssembler.ts` + - `assistantEvidenceBundleAssembler.ts` + - `assistantOrchestrationContracts.ts` + - introduced `AssistantRetrievalRawResult` and typed `AssistantRetrievalRawResultRecord`; + - retrieval calls now use `AssistantRetrievalCallRecord[]` end-to-end. +2. Preserved behavior: + - no runtime logic changes; only stronger typing and safe raw normalization. + +Validation: +1. `npm run build` passed. +2. Targeted deep retrieval/response pack passed: + - `assistantDeepTurnResponseRuntimeAdapter.test.ts` + - `assistantDeepTurnRetrievalRuntimeAdapter.test.ts` + - `assistantDeepTurnPackaging.test.ts` + +Implemented in current pass (Phase 2.125 + 2.126 + 2.127 + 2.128): +1. Tightened deep turn execution state + fallback metadata typing: + - `assistantDeepTurnPrePackagingContext.ts` + - `assistantDeepTurnPackaging.ts` + - `assistantDeepTurnPackagingRuntimeAdapter.ts` + - `assistantDeepTurnInputBuilder.ts` + - `assistantDeepTurnResponseRuntimeAdapter.ts` + - `assistantDeepTurnNormalizationRuntimeAdapter.ts` + - added `AssistantExecutionStateRecord` + `AssistantAddressRuntimeMetaForDeep`; + - `fallback_type` now `AssistantFallbackType`; + - `problem_answer_mode` now `AssistantProblemAnswerMode`; + - `problem_unit_ids_used` now `string[]`; + - `investigationStateSnapshot` now `InvestigationStateWithProblemUnits | null`. +2. Aligned debug/log payload typing with contracts: + - `assistantDebugPayloadAssembler.ts` + - `assistantMessageLogAssembler.ts` + - `assistantOrchestrationContractsV1` and `outcomeClassV1` now typed; + - `answerStructureV11` now typed. +3. Preserved behavior: + - no runtime logic changes; type alignment only. + +Validation: +1. Not run in this pass (type-only changes). + +Implemented in current pass (Phase 2.129 + 2.130 + 2.131 + 2.132): +1. Typified debug route structures end-to-end: + - `assistantQueryPlanning.ts` + - `assistantDeepTurnPrePackagingContext.ts` + - `assistantDeepTurnPackaging.ts` + - `assistantDeepTurnPackagingRuntimeAdapter.ts` + - `assistantDeepTurnInputBuilder.ts` + - `assistantDeepTurnResponseRuntimeAdapter.ts` + - `assistantDebugPayloadAssembler.ts` + - `assistantMessageLogAssembler.ts` + - introduced `AssistantDebugRouteRecord` union (legacy vs deterministic debug routes); + - `routes` now typed in `AssistantDebugPayload`. +2. Preserved behavior: + - no runtime logic changes; type alignment only. + +Validation: +1. Not run in this pass (type-only changes). + +Implemented in current pass (Phase 2.133): +1. Tightened deep retrieval runtime input: + - `assistantDeepTurnRetrievalRuntimeAdapter.ts` + - `executeRouteRuntime` now returns `AssistantRetrievalRawResult` (explicit union). +2. Preserved behavior: + - no runtime logic changes; type alignment only. + +Validation: +1. Not run in this pass (type-only changes). + +Implemented in current pass (Phase 2.134 + 2.135): +1. Typed live-route plan audit contract: + - `assistantDeepTurnPlanRuntimeAdapter.ts` + - introduced `AssistantLiveRoutePlanAudit` for plan enforcement audits. +2. Typed deep analysis log payload plumbing: + - `assistantMessageLogAssembler.ts` + - `assistantDeepTurnPackaging.ts` + - `assistantDeepTurnPackagingRuntimeAdapter.ts` + - `assistantDeepTurnFinalizeRuntimeAdapter.ts` + - introduced `DeepAnalysisLogDetails` alias and used it end-to-end. +3. Preserved behavior: + - no runtime logic changes; type alignment only. + +Validation: +1. Not run in this pass (type-only changes). + +Implemented in current pass (Phase 2.136): +1. Tightened business-scope resolution contract shape: + - `assistantDeepTurnContextRuntimeAdapter.ts` + - removed index-signature `unknown` on business scope resolution; + - `resolveBusinessScopeFromLiveContext` now uses `AssistantBusinessScopeResolution` explicitly. +2. Preserved behavior: + - no runtime logic changes; type alignment only. + +Validation: +1. Not run in this pass (type-only changes). + +Implemented in current pass (Phase 2.137 + 2.138): +1. Tightened company anchor normalization input types: + - `assistantDeepTurnCompositionRuntimeAdapter.ts` + - `toStringArray` now accepts `string[] | null | undefined`; + - company anchor normalization now consumes `Partial`. +2. Narrowed response runtime normalizers: + - `assistantDeepTurnResponseRuntimeAdapter.ts` + - runtime analysis context and business scope normalizers now take typed inputs. +3. Preserved behavior: + - no runtime logic changes; type alignment only. + +Validation: +1. Not run in this pass (type-only changes). + +Implemented in current pass (Phase 2.139 + 2.140): +1. Tightened analysis attempt builder normalizers: + - `assistantDeepTurnAnalysisAttemptInputBuilder.ts` + - removed `unknown` from anchor/period helpers; now `Partial` + typed primary period. +2. Narrowed response runtime normalization helpers: + - `assistantDeepTurnResponseRuntimeAdapter.ts` + - execution plan normalization now consumes typed `AssistantExecutionPlanItem[]`; + - helper signatures no longer accept `unknown` where input is already typed. +3. Preserved behavior: + - no runtime logic changes; type alignment only. + +Validation: +1. Not run in this pass (type-only changes). + +Implemented in current pass (Phase 2.141 + 2.142 + 2.143 + 2.144): +1. Tightened attempt input defaults: + - `assistantDeepTurnAttemptInputBuilder.ts` + - response attempt default type is now `AssistantMessageResponsePayload`. +2. Tightened retrieval raw result typing: + - `assistantDeepTurnRetrievalRuntimeAdapter.ts` + - introduced `AssistantRetrievalRawResultLike` + list item union. +3. Tightened deep packaging normalization: + - `assistantDeepTurnPackaging.ts` + - normalized fragments extracted without `Record` cast. +4. Simplified response runtime normalizers: + - `assistantDeepTurnResponseRuntimeAdapter.ts` + - removed `toRecordObject` casts and normalized from typed inputs. +5. Preserved behavior: + - no runtime logic changes; type alignment only. + +Validation: +1. Not run in this pass (type-only changes). + +Implemented in current pass (Phase 2.145 + 2.146): +1. Tightened retrieval raw result field shapes: + - `assistantDeepTurnRetrievalRuntimeAdapter.ts` + - introduced `AssistantRetrievalFieldValue` / `AssistantRetrievalRecord`; + - removed `unknown` from raw result record types. +2. Tightened normalized fragment extraction: + - `assistantDeepTurnPackaging.ts` + - normalized fragments now typed to `NormalizedQueryV2*` fragments. +3. Preserved behavior: + - no runtime logic changes; type alignment only. + +Validation: +1. Not run in this pass (type-only changes). + +Status: **Completed (Phase 2.1–2.146)** + +### Stage 2 Completion Report (Summary) +1. Orchestration monolith decomposed into explicit modules: + - QueryFrame, ExecutionPlan, EvidenceBundle, Coverage/Grounding, Answer package, Debug payload, Log details. +2. Deep lane now uses stable contracts end-to-end: + - `assistant_orchestration_contracts_v1`, `assistant_evidence_bundle_v1`, `assistant_coverage_contract_v1`. +3. Audit & trace coverage standardized: + - temporal/polarity/claim/evidence guards, live-route audits, followup usage, outcome class. +4. Type hardening complete across deep chain: + - normalized payloads, execution plan, retrieval calls/raw, debug routes, runtime meta, investigation state. +5. Behavior preserved throughout refactor (no route/answer regressions by design). + +### Stage 2 Closure Audit (2026-04-11) +1. Fixed runtime-critical context loss in `assistantTurnRuntimeDepsAdapter.ts`: + - unbound session store/logger/normalizer methods caused `TypeError` at `assistantSessionStore.ensureSession(...)` and mass `500` responses in API tests. +2. Added safe method wrappers in deps adapter: + - `ensureSession`, `appendItem`, `getSession`, `persistSession`, `setInvestigationState`, `normalize`. +3. Added regression guard: + - `assistantTurnRuntimeDepsAdapter.test.ts` now includes a stateful instance-context test to prevent `this` loss regressions. +4. Validation gates (fact): + - `npm run build` passed. + - Combined Stage 2 regression validation passed: `37` files / `95` tests (deep-turn adapters/builders/packaging, orchestration contracts/runtime, MCP bridge, followup continuity, wave10 corrective regression). +5. Scope note: + - Full backend suite still has red tests in Stage 3/4 probes and long-running acceptance packs; this is tracked under Stage 3 backlog and is not a Stage 2 blocker. + +### Stage 2 Remaining Risks (Known) +1. Final answer quality still template-heavy and brittle. +2. Lexical routing pressure remains high (dictionary overfitting risk). +3. Deterministic guards still compensate for weak semantic parsing. ## Stage 3 (P2): Hybrid Semantic Layer (LLM + Deterministic Guards) @@ -2105,6 +2334,27 @@ Goal: 2. Keep deterministic guardrails as verifier, not primary “brain”. 3. Reduce dictionary overfitting and false route drifts. +Plan (Stage 3): +1. **Schema-first semantic extraction** + - Strict JSON schema for: entities, time scope, intent, ambiguity, success criteria. + - Hard validation + retry/repair loop. +2. **LLM decomposition with guardrails** + - Decomposition produces executable plan candidates. + - Deterministic guards validate: domain polarity, temporal window, claim-bound anchors. +3. **Evidence-first reasoning** + - LLM only summarizes from evidence bundle, never invents facts. +4. **Context binding** + - Carryover only via typed followup state, not free-text memory. +5. **Quality gates** + - Coverage critic threshold before final answer. + - Reason-code taxonomy normalized. + +Acceptance (Stage 3): +1. LLM outputs strictly validated schema for extraction/decomposition (no free-form). +2. Deterministic guards can block or downgrade answers when evidence insufficient. +3. False route drifts and generic responses reduced in regression packs. +4. Manual markup shows increase in “correct/grounded” labels. + Status: Planned ## Stage 4 (P2): Human-Centric Answer Layer diff --git a/llm_normalizer/backend/dist/services/assistantDeepTurnAnalysisAttemptInputBuilder.js b/llm_normalizer/backend/dist/services/assistantDeepTurnAnalysisAttemptInputBuilder.js index 236fd8d..cccc69e 100644 --- a/llm_normalizer/backend/dist/services/assistantDeepTurnAnalysisAttemptInputBuilder.js +++ b/llm_normalizer/backend/dist/services/assistantDeepTurnAnalysisAttemptInputBuilder.js @@ -16,12 +16,6 @@ const KNOWN_GUARD_DOMAINS = [ "month_close_costs_20_44", "fixed_asset_amortization" ]; -function toRecordObject(value) { - if (!value || typeof value !== "object" || Array.isArray(value)) { - return null; - } - return value; -} function toStringArray(value) { if (!Array.isArray(value)) { return []; @@ -31,10 +25,10 @@ function toStringArray(value) { .filter((item) => item.length > 0); } function toCompanyAnchorSet(value) { - const source = toRecordObject(value); - if (!source) { + if (!value || typeof value !== "object" || Array.isArray(value)) { return null; } + const source = value; return { contract_numbers: toStringArray(source.contract_numbers), document_numbers: toStringArray(source.document_numbers), @@ -47,13 +41,12 @@ function toCompanyAnchorSet(value) { }; } function toClaimBoundPrimaryPeriod(value) { - const source = toRecordObject(value); - if (!source) { + if (!value || typeof value !== "object") { return null; } - const from = typeof source.from === "string" ? source.from.trim() : ""; - const to = typeof source.to === "string" ? source.to.trim() : ""; - const granularity = source.granularity === "day" || source.granularity === "month" ? source.granularity : null; + const from = typeof value.from === "string" ? value.from.trim() : ""; + const to = typeof value.to === "string" ? value.to.trim() : ""; + const granularity = value.granularity === "day" || value.granularity === "month" ? value.granularity : null; if (!from || !to || !granularity) { return null; } diff --git a/llm_normalizer/backend/dist/services/assistantDeepTurnNormalizationRuntimeAdapter.js b/llm_normalizer/backend/dist/services/assistantDeepTurnNormalizationRuntimeAdapter.js index 1c99803..f679adf 100644 --- a/llm_normalizer/backend/dist/services/assistantDeepTurnNormalizationRuntimeAdapter.js +++ b/llm_normalizer/backend/dist/services/assistantDeepTurnNormalizationRuntimeAdapter.js @@ -2,13 +2,16 @@ Object.defineProperty(exports, "__esModule", { value: true }); exports.buildAssistantDeepTurnNormalizationRuntime = buildAssistantDeepTurnNormalizationRuntime; async function buildAssistantDeepTurnNormalizationRuntime(input) { - const followupBinding = input.featureInvestigationStateV1 && + const investigationState = input.sessionInvestigationState; + const canUseFollowupBinding = input.featureInvestigationStateV1 && input.featureStateFollowupBindingV1 && - Boolean(input.sessionInvestigationState) + investigationState !== null && + investigationState !== undefined; + const followupBinding = canUseFollowupBinding ? input.buildFollowupStateBinding({ userMessage: input.userMessage, payloadContext: input.payload.context, - investigationState: input.sessionInvestigationState + investigationState }) : { normalizedQuestion: input.userMessage, diff --git a/llm_normalizer/backend/dist/services/assistantDeepTurnPackaging.js b/llm_normalizer/backend/dist/services/assistantDeepTurnPackaging.js index eb4282a..8372b8b 100644 --- a/llm_normalizer/backend/dist/services/assistantDeepTurnPackaging.js +++ b/llm_normalizer/backend/dist/services/assistantDeepTurnPackaging.js @@ -6,9 +6,16 @@ const assistantContractsBundleAssembler_1 = require("./assistantContractsBundleA const assistantDeepResponseAssembler_1 = require("./assistantDeepResponseAssembler"); const assistantDebugPayloadAssembler_1 = require("./assistantDebugPayloadAssembler"); const assistantMessageLogAssembler_1 = require("./assistantMessageLogAssembler"); +function extractNormalizedFragments(normalized) { + if (!normalized || typeof normalized !== "object") { + return []; + } + const source = normalized; + return Array.isArray(source.fragments) ? source.fragments : []; +} function assembleAssistantDeepTurnPackaging(input) { - const normalizedPayload = (input.normalized.normalized ?? null); - const normalizedFragments = Array.isArray(normalizedPayload?.["fragments"]) ? normalizedPayload?.["fragments"] : []; + const normalizedPayload = input.normalized.normalized ?? null; + const normalizedFragments = extractNormalizedFragments(normalizedPayload); const evidenceBundleAssembly = (0, assistantEvidenceBundleAssembler_1.assembleAssistantEvidenceBundle)({ retrievalCalls: input.retrievalCalls, retrievalResults: input.retrievalResults diff --git a/llm_normalizer/backend/dist/services/assistantDeepTurnResponseRuntimeAdapter.js b/llm_normalizer/backend/dist/services/assistantDeepTurnResponseRuntimeAdapter.js index cda1ab6..512fbb2 100644 --- a/llm_normalizer/backend/dist/services/assistantDeepTurnResponseRuntimeAdapter.js +++ b/llm_normalizer/backend/dist/services/assistantDeepTurnResponseRuntimeAdapter.js @@ -3,12 +3,6 @@ Object.defineProperty(exports, "__esModule", { value: true }); exports.runAssistantDeepTurnResponseRuntime = runAssistantDeepTurnResponseRuntime; const assistantDeepTurnPackagingRuntimeAdapter_1 = require("./assistantDeepTurnPackagingRuntimeAdapter"); const assistantDeepTurnFinalizeRuntimeAdapter_1 = require("./assistantDeepTurnFinalizeRuntimeAdapter"); -function toRecordObject(value) { - if (!value || typeof value !== "object") { - return null; - } - return value; -} function toNullableString(value) { if (typeof value !== "string") { return null; @@ -31,31 +25,17 @@ function normalizeExecutionPlan(value) { if (!Array.isArray(value)) { return []; } - return value.map((item, index) => { - const source = toRecordObject(item); - return { - fragment_id: toNullableString(source?.fragment_id) ?? `fragment_${index + 1}`, - requirement_ids: toStringArray(source?.requirement_ids), - route: toNullableString(source?.route) ?? "unknown_route", - should_execute: Boolean(source?.should_execute), - no_route_reason: toNullableString(source?.no_route_reason), - clarification_reason: toNullableString(source?.clarification_reason) - }; - }); -} -function normalizeRecordArray(value) { - if (!Array.isArray(value)) { - return []; - } - return value - .map((item) => toRecordObject(item)) - .filter((item) => Boolean(item)); -} -function normalizeRecord(value) { - return toRecordObject(value) ?? {}; + return value.map((item, index) => ({ + fragment_id: toNullableString(item.fragment_id) ?? `fragment_${index + 1}`, + requirement_ids: toStringArray(item.requirement_ids), + route: toNullableString(item.route) ?? "unknown_route", + should_execute: Boolean(item.should_execute), + no_route_reason: toNullableString(item.no_route_reason ?? null), + clarification_reason: toNullableString(item.clarification_reason ?? null) + })); } function normalizeRuntimeAnalysisContext(value) { - const source = toRecordObject(value); + const source = value; return { active: Boolean(source?.active), as_of_date: toNullableString(source?.as_of_date), @@ -66,7 +46,7 @@ function normalizeRuntimeAnalysisContext(value) { }; } function normalizeBusinessScopeResolution(value) { - const source = toRecordObject(value); + const source = value; return { business_scope_raw: toStringArray(source?.business_scope_raw), business_scope_resolved: toStringArray(source?.business_scope_resolved), @@ -75,7 +55,7 @@ function normalizeBusinessScopeResolution(value) { }; } function normalizeAddressRuntimeMetaForDeep(value) { - const source = toRecordObject(value); + const source = value; if (!source) { return null; } @@ -87,8 +67,8 @@ function normalizeAddressRuntimeMetaForDeep(value) { fallbackRuleHit: toNullableString(source.fallbackRuleHit), toolGateDecision: toNullableString(source.toolGateDecision), toolGateReason: toNullableString(source.toolGateReason), - predecomposeContract: toRecordObject(source.predecomposeContract), - orchestrationContract: toRecordObject(source.orchestrationContract) + predecomposeContract: source.predecomposeContract ?? null, + orchestrationContract: source.orchestrationContract ?? null }; } function runAssistantDeepTurnResponseRuntime(input) { @@ -107,21 +87,21 @@ function runAssistantDeepTurnResponseRuntime(input) { coverageEvaluationRequirements: input.coverageEvaluationRequirements, coverageReport: input.coverageReport, groundingCheck: input.groundingCheck, - retrievalCalls: normalizeRecordArray(input.retrievalCalls), - retrievalResultsRaw: Array.isArray(input.retrievalResultsRaw) ? input.retrievalResultsRaw : [], + retrievalCalls: input.retrievalCalls, + retrievalResultsRaw: input.retrievalResultsRaw, retrievalResults: input.retrievalResults, questionTypeClass: input.questionTypeClass, companyAnchors: input.companyAnchors, runtimeAnalysisContext: normalizeRuntimeAnalysisContext(input.runtimeAnalysisContext), businessScopeResolution: normalizeBusinessScopeResolution(input.businessScopeResolution), - temporalGuard: normalizeRecord(input.temporalGuard), - polarityAudit: normalizeRecord(input.polarityAudit), - claimAnchorAudit: normalizeRecord(input.claimAnchorAudit), + temporalGuard: input.temporalGuard, + polarityAudit: input.polarityAudit, + claimAnchorAudit: input.claimAnchorAudit, targetedEvidenceAudit: input.targetedEvidenceAudit, evidenceAdmissibilityGateAudit: input.evidenceAdmissibilityGateAudit, rbpLiveRouteAudit: input.rbpLiveRouteAudit ?? null, faLiveRouteAudit: input.faLiveRouteAudit ?? null, - groundedAnswerEligibilityGuard: normalizeRecord(input.groundedAnswerEligibilityGuard), + groundedAnswerEligibilityGuard: input.groundedAnswerEligibilityGuard, followupStateUsage: input.followupStateUsage, followupApplied: input.followupApplied, composition: input.composition, diff --git a/llm_normalizer/backend/dist/services/assistantDeepTurnRetrievalRuntimeAdapter.js b/llm_normalizer/backend/dist/services/assistantDeepTurnRetrievalRuntimeAdapter.js index 5dfe69f..37897f2 100644 --- a/llm_normalizer/backend/dist/services/assistantDeepTurnRetrievalRuntimeAdapter.js +++ b/llm_normalizer/backend/dist/services/assistantDeepTurnRetrievalRuntimeAdapter.js @@ -20,6 +20,21 @@ function buildRouteExecutorErrorRawResult(route, message) { errors: [message] }; } +function normalizeRawResult(value) { + if (value === null || value === undefined) { + return null; + } + if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") { + return value; + } + if (Array.isArray(value)) { + return value; + } + if (typeof value === "object") { + return value; + } + return null; +} async function executeAssistantDeepTurnRetrievalPlan(input) { const normalizeRetrievalResultSafe = input.normalizeRetrievalResultFn ?? retrievalResultNormalizer_1.normalizeRetrievalResult; const retrievalCalls = []; @@ -50,12 +65,13 @@ async function executeAssistantDeepTurnRetrievalPlan(input) { const raw = await input.executeRouteRuntime(planItem.route, planItem.fragment_text, { temporalHint: input.liveTemporalHint }); + const normalizedRaw = normalizeRawResult(raw); retrievalResultsRaw.push({ fragment_id: planItem.fragment_id, route: planItem.route, - raw_result: raw + raw_result: normalizedRaw }); - retrievalResults.push(normalizeRetrievalResultSafe(planItem.fragment_id, planItem.requirement_ids, planItem.route, raw)); + retrievalResults.push(normalizeRetrievalResultSafe(planItem.fragment_id, planItem.requirement_ids, planItem.route, normalizedRaw)); } catch (error) { const message = error instanceof Error ? error.message : String(error); diff --git a/llm_normalizer/backend/dist/services/assistantTurnRuntimeDepsAdapter.js b/llm_normalizer/backend/dist/services/assistantTurnRuntimeDepsAdapter.js index 23ecdb3..a515a86 100644 --- a/llm_normalizer/backend/dist/services/assistantTurnRuntimeDepsAdapter.js +++ b/llm_normalizer/backend/dist/services/assistantTurnRuntimeDepsAdapter.js @@ -4,12 +4,12 @@ exports.buildAssistantTurnRuntimeDeps = buildAssistantTurnRuntimeDeps; function buildAssistantTurnRuntimeDeps(input) { return { ...input.helpers, - ensureSession: input.sessions.ensureSession, - appendItem: input.sessions.appendItem, - getSession: input.sessions.getSession, - persistSession: input.sessionLogger.persistSession, - setInvestigationState: input.sessions.setInvestigationState, - normalize: input.normalizerService.normalize, + ensureSession: (sessionId) => input.sessions.ensureSession(sessionId), + appendItem: (sessionId, item) => input.sessions.appendItem(sessionId, item), + getSession: (sessionId) => input.sessions.getSession(sessionId), + persistSession: (session) => input.sessionLogger.persistSession(session), + setInvestigationState: (sessionId, state) => input.sessions.setInvestigationState(sessionId, state), + normalize: (payload) => input.normalizerService.normalize(payload), executeRouteRuntime: (route, fragmentText, options) => input.dataLayer.executeRouteRuntime(route, fragmentText, options), tryAddressQueryHandle: (messageUsed, options) => input.addressQueryService.tryHandle(messageUsed, options), chatClient: input.chatClient, diff --git a/llm_normalizer/backend/src/services/assistantAddressOrchestrationRuntimeAdapter.ts b/llm_normalizer/backend/src/services/assistantAddressOrchestrationRuntimeAdapter.ts index 0db697a..62cd403 100644 --- a/llm_normalizer/backend/src/services/assistantAddressOrchestrationRuntimeAdapter.ts +++ b/llm_normalizer/backend/src/services/assistantAddressOrchestrationRuntimeAdapter.ts @@ -22,6 +22,7 @@ export interface BuildAssistantAddressOrchestrationRuntimeInput { effectiveAddressUserMessage: string; followupContext: unknown; llmPreDecomposeMeta: Record; + sessionItems?: unknown[]; useMock: boolean; }) => Record; buildAddressDialogContinuationContractV2: ( @@ -102,6 +103,7 @@ export async function buildAssistantAddressOrchestrationRuntime( effectiveAddressUserMessage: addressInputMessage, followupContext, llmPreDecomposeMeta: addressPreDecompose, + sessionItems: input.sessionItems, useMock: input.useMock }); const dialogContinuationContract = input.buildAddressDialogContinuationContractV2( diff --git a/llm_normalizer/backend/src/services/assistantDebugPayloadAssembler.ts b/llm_normalizer/backend/src/services/assistantDebugPayloadAssembler.ts index da9df9e..bae8f3b 100644 --- a/llm_normalizer/backend/src/services/assistantDebugPayloadAssembler.ts +++ b/llm_normalizer/backend/src/services/assistantDebugPayloadAssembler.ts @@ -1,4 +1,28 @@ -import type { AssistantDebugPayload } from "../types/assistant"; +import type { + AssistantAddressRuntimeMetaForDeep, + AssistantDebugPayload, + AssistantDebugRouteRecord, + AssistantFallbackType, + AssistantProblemAnswerMode, + AssistantRequirement, + UnifiedRetrievalResult, + FaLiveRouteAuditDebug, + RbpLiveRouteAuditDebug +} from "../types/assistant"; +import type { NormalizeResponsePayload, RouteHintSummary } from "../types/normalizer"; +import type { AnswerStructureV11 } from "../types/stage1Contracts"; +import type { InvestigationStateWithProblemUnits } from "../types/stage2ProblemUnits"; +import type { ClaimBoundAnchorAudit, TargetedEvidenceAcquisitionAudit } from "./assistantClaimBoundEvidence"; +import type { AssistantContractsBundleV1 } from "./assistantContractsBundleAssembler"; +import type { AssistantOutcomeClassV1 } from "./assistantOrchestrationContracts"; +import type { AssistantFollowupUsage } from "./assistantFollowupUsage"; +import type { CompanyAnchorSet } from "./companyAnchorResolver"; +import type { + DomainPolarityGuardAudit, + EvidenceAdmissibilityAudit, + GroundedAnswerEligibilityAudit, + TemporalGuardAudit +} from "./assistantRuntimeGuards"; type RetrievalStatusItem = AssistantDebugPayload["retrieval_status"][number]; @@ -6,18 +30,18 @@ export interface DeepAnalysisDebugPayloadInput { traceId: string; promptVersion: string; schemaVersion: string; - fallbackType: unknown; - routeSummary: unknown; + fallbackType: AssistantFallbackType; + routeSummary: RouteHintSummary | null; fragments: unknown[]; - requirementsExtracted: unknown[]; - coverageReport: unknown; - routes: Array>; + requirementsExtracted: AssistantRequirement[]; + coverageReport: AssistantDebugPayload["coverage_report"]; + routes: AssistantDebugRouteRecord[]; retrievalStatus: RetrievalStatusItem[]; - retrievalResults: unknown[]; - groundingCheck: unknown; + retrievalResults: UnifiedRetrievalResult[]; + groundingCheck: AssistantDebugPayload["answer_grounding_check"]; droppedIntentSegments: string[]; questionTypeClass: string; - companyAnchors: unknown; + companyAnchors: CompanyAnchorSet | null; runtimeAnalysisContext: { active: boolean; as_of_date: string | null; @@ -32,40 +56,27 @@ export interface DeepAnalysisDebugPayloadInput { company_grounding_applied?: boolean; scope_resolution_reason?: string[]; }; - temporalGuard: Record; - polarityAudit: Record; - claimAnchorAudit: Record; - targetedEvidenceAudit: unknown; - evidenceAdmissibilityGateAudit: unknown; - rbpLiveRouteAudit: unknown | null; - faLiveRouteAudit: unknown | null; - groundedAnswerEligibilityGuard: Record; - followupStateUsage: unknown | null; + temporalGuard: TemporalGuardAudit; + polarityAudit: DomainPolarityGuardAudit; + claimAnchorAudit: ClaimBoundAnchorAudit; + targetedEvidenceAudit: TargetedEvidenceAcquisitionAudit; + evidenceAdmissibilityGateAudit: EvidenceAdmissibilityAudit; + rbpLiveRouteAudit: RbpLiveRouteAuditDebug | null; + faLiveRouteAudit: FaLiveRouteAuditDebug | null; + groundedAnswerEligibilityGuard: GroundedAnswerEligibilityAudit; + followupStateUsage: AssistantFollowupUsage | null; compositionDebug: { problem_centric_answer_applied?: boolean; problem_units_used_count?: number; - problem_answer_mode?: string; + problem_answer_mode?: AssistantProblemAnswerMode; problem_unit_ids_used?: string[]; }; - addressRuntimeMetaForDeep: - | { - attempted?: boolean; - applied?: boolean; - reason?: string | null; - provider?: string | null; - fallbackRuleHit?: string | null; - toolGateDecision?: string | null; - toolGateReason?: string | null; - predecomposeContract?: unknown; - orchestrationContract?: unknown; - } - | null - | undefined; - outcomeClassV1: unknown; - assistantOrchestrationContractsV1: unknown; - answerStructureV11: unknown; - investigationStateSnapshot: unknown; - normalizedPayload: unknown; + addressRuntimeMetaForDeep: AssistantAddressRuntimeMetaForDeep | null | undefined; + outcomeClassV1: AssistantOutcomeClassV1; + assistantOrchestrationContractsV1: AssistantContractsBundleV1["assistantOrchestrationContractsV1"]; + answerStructureV11: AnswerStructureV11 | null; + investigationStateSnapshot: InvestigationStateWithProblemUnits | null; + normalizedPayload: NormalizeResponsePayload["normalized"]; } function toAnalysisContext(input: DeepAnalysisDebugPayloadInput["runtimeAnalysisContext"]): Record | null { diff --git a/llm_normalizer/backend/src/services/assistantDeepTurnAnalysisAttemptInputBuilder.ts b/llm_normalizer/backend/src/services/assistantDeepTurnAnalysisAttemptInputBuilder.ts index 73f53e6..0e38c05 100644 --- a/llm_normalizer/backend/src/services/assistantDeepTurnAnalysisAttemptInputBuilder.ts +++ b/llm_normalizer/backend/src/services/assistantDeepTurnAnalysisAttemptInputBuilder.ts @@ -49,14 +49,7 @@ const KNOWN_GUARD_DOMAINS = [ "fixed_asset_amortization" ] as const; -function toRecordObject(value: unknown): Record | null { - if (!value || typeof value !== "object" || Array.isArray(value)) { - return null; - } - return value as Record; -} - -function toStringArray(value: unknown): string[] { +function toStringArray(value: string[] | null | undefined): string[] { if (!Array.isArray(value)) { return []; } @@ -65,11 +58,11 @@ function toStringArray(value: unknown): string[] { .filter((item) => item.length > 0); } -function toCompanyAnchorSet(value: unknown): CompanyAnchorSet | null { - const source = toRecordObject(value); - if (!source) { +function toCompanyAnchorSet(value: Partial | null | undefined): CompanyAnchorSet | null { + if (!value || typeof value !== "object" || Array.isArray(value)) { return null; } + const source: Partial = value; return { contract_numbers: toStringArray(source.contract_numbers), document_numbers: toStringArray(source.document_numbers), @@ -82,14 +75,13 @@ function toCompanyAnchorSet(value: unknown): CompanyAnchorSet | null { }; } -function toClaimBoundPrimaryPeriod(value: unknown): ClaimBoundPrimaryPeriod { - const source = toRecordObject(value); - if (!source) { +function toClaimBoundPrimaryPeriod(value: ClaimBoundPrimaryPeriod | null | undefined): ClaimBoundPrimaryPeriod { + if (!value || typeof value !== "object") { return null; } - const from = typeof source.from === "string" ? source.from.trim() : ""; - const to = typeof source.to === "string" ? source.to.trim() : ""; - const granularity = source.granularity === "day" || source.granularity === "month" ? source.granularity : null; + const from = typeof value.from === "string" ? value.from.trim() : ""; + const to = typeof value.to === "string" ? value.to.trim() : ""; + const granularity = value.granularity === "day" || value.granularity === "month" ? value.granularity : null; if (!from || !to || !granularity) { return null; } @@ -101,7 +93,7 @@ function toClaimBoundPrimaryPeriod(value: unknown): ClaimBoundPrimaryPeriod { } function normalizeFocusDomainForGuards( - value: unknown + value: string | null | undefined ): AssistantDeepTurnRetrievalGuardPipelineInput["focusDomainForGuards"] { const normalized = typeof value === "string" ? value.trim() : ""; if (!normalized) { diff --git a/llm_normalizer/backend/src/services/assistantDeepTurnAttemptInputBuilder.ts b/llm_normalizer/backend/src/services/assistantDeepTurnAttemptInputBuilder.ts index 8704470..22ea1bc 100644 --- a/llm_normalizer/backend/src/services/assistantDeepTurnAttemptInputBuilder.ts +++ b/llm_normalizer/backend/src/services/assistantDeepTurnAttemptInputBuilder.ts @@ -5,6 +5,7 @@ import type { import type { RunAssistantDeepTurnAnalysisAttemptRuntimeInput } from "./assistantDeepTurnAnalysisAttemptRuntimeAdapter"; import type { RunAssistantDeepTurnAnalysisRuntimeOutput } from "./assistantDeepTurnAnalysisRuntimeAdapter"; import type { RunAssistantDeepTurnResponseAttemptRuntimeInput } from "./assistantDeepTurnResponseAttemptRuntimeAdapter"; +import type { AssistantMessageResponsePayload } from "../types/assistant"; import { isAssistantFollowupApplied } from "./assistantFollowupUsage"; export interface BuildAssistantDeepTurnNormalizationRuntimeInputInput { @@ -88,7 +89,7 @@ export function buildAssistantDeepTurnAnalysisAttemptRuntimeInput( }; } -export interface BuildAssistantDeepTurnResponseAttemptRuntimeInputInput { +export interface BuildAssistantDeepTurnResponseAttemptRuntimeInputInput { featureInvestigationStateV1: boolean; featureContractsV11: boolean; featureAnswerPolicyV11: boolean; @@ -115,7 +116,7 @@ export interface BuildAssistantDeepTurnResponseAttemptRuntimeInputInput( +export function buildAssistantDeepTurnResponseAttemptRuntimeInput( input: BuildAssistantDeepTurnResponseAttemptRuntimeInputInput ): RunAssistantDeepTurnResponseAttemptRuntimeInput { return { diff --git a/llm_normalizer/backend/src/services/assistantDeepTurnCompositionRuntimeAdapter.ts b/llm_normalizer/backend/src/services/assistantDeepTurnCompositionRuntimeAdapter.ts index 0b3451a..66dc34e 100644 --- a/llm_normalizer/backend/src/services/assistantDeepTurnCompositionRuntimeAdapter.ts +++ b/llm_normalizer/backend/src/services/assistantDeepTurnCompositionRuntimeAdapter.ts @@ -16,7 +16,7 @@ export interface BuildAssistantDeepTurnCompositionInput { groundingCheck: AnswerGroundingCheck; followupUsage: AssistantFollowupUsage | null | undefined; investigationState: InvestigationStateWithProblemUnits | null | undefined; - companyAnchors: unknown; + companyAnchors: CompanyAnchorSet | null; normalizedPayload: NormalizeResponsePayload["normalized"]; featureAnswerPolicyV11: boolean; featureProblemCentricAnswerV1: boolean; @@ -34,7 +34,7 @@ export interface AssistantDeepTurnCompositionOutput { composition: ReturnType; } -function toStringArray(value: unknown): string[] { +function toStringArray(value: string[] | null | undefined): string[] { if (!Array.isArray(value)) { return []; } @@ -43,11 +43,11 @@ function toStringArray(value: unknown): string[] { .filter((item) => item.length > 0); } -function normalizeCompanyAnchorSet(value: unknown): CompanyAnchorSet | null { +function normalizeCompanyAnchorSet(value: Partial | null | undefined): CompanyAnchorSet | null { if (!value || typeof value !== "object" || Array.isArray(value)) { return null; } - const source = value as Record; + const source: Partial = value; return { contract_numbers: toStringArray(source.contract_numbers), document_numbers: toStringArray(source.document_numbers), diff --git a/llm_normalizer/backend/src/services/assistantDeepTurnContextRuntimeAdapter.ts b/llm_normalizer/backend/src/services/assistantDeepTurnContextRuntimeAdapter.ts index 43a7def..1ebbf74 100644 --- a/llm_normalizer/backend/src/services/assistantDeepTurnContextRuntimeAdapter.ts +++ b/llm_normalizer/backend/src/services/assistantDeepTurnContextRuntimeAdapter.ts @@ -61,14 +61,11 @@ export interface BuildAssistantDeepTurnRuntimeContextInput { userMessage: string; companyAnchors: CompanyAnchorSet; focusDomainHint: string | null; - primaryPeriod: unknown; + primaryPeriod: ClaimBoundAnchorAudit["primary_period"] | null; }) => ClaimBoundAnchorAudit; resolveBusinessScopeFromLiveContext: (input: { - current: { - route_summary_resolved: RouteHintSummary | null; - [key: string]: unknown; - }; - temporalGuard: unknown; + current: AssistantBusinessScopeResolution; + temporalGuard: TemporalGuardAudit; claimType: string; focusDomainHint: string | null; userMessage: string; @@ -83,7 +80,6 @@ export interface AssistantBusinessScopeResolution { business_scope_resolved?: string[]; company_grounding_applied?: boolean; scope_resolution_reason?: string[]; - [key: string]: unknown; } export interface BuildAssistantDeepTurnRuntimeContextOutput { diff --git a/llm_normalizer/backend/src/services/assistantDeepTurnFinalizeRuntimeAdapter.ts b/llm_normalizer/backend/src/services/assistantDeepTurnFinalizeRuntimeAdapter.ts index 88e8b00..974fe0c 100644 --- a/llm_normalizer/backend/src/services/assistantDeepTurnFinalizeRuntimeAdapter.ts +++ b/llm_normalizer/backend/src/services/assistantDeepTurnFinalizeRuntimeAdapter.ts @@ -1,4 +1,5 @@ import type { AssistantConversationItem, AssistantDebugPayload, AssistantMessageResponsePayload, AssistantReplyType } from "../types/assistant"; +import type { DeepAnalysisLogDetails } from "./assistantMessageLogAssembler"; import { buildAssistantDeepTurnSuccessResponse } from "./assistantDeepTurnResponseBuilder"; import type { CommitAssistantTurnAndLogOutput } from "./assistantTurnCommitRuntimeAdapter"; import { commitAssistantTurnAndLog } from "./assistantTurnCommitRuntimeAdapter"; @@ -9,7 +10,7 @@ export interface FinalizeAssistantDeepTurnInput { replyType: AssistantReplyType; assistantItem: AssistantConversationItem; debug: AssistantDebugPayload; - deepAnalysisLogDetails: Record; + deepAnalysisLogDetails: DeepAnalysisLogDetails; appendItem: Parameters[0]["appendItem"]; getSession: Parameters[0]["getSession"]; persistSession: Parameters[0]["persistSession"]; diff --git a/llm_normalizer/backend/src/services/assistantDeepTurnInputBuilder.ts b/llm_normalizer/backend/src/services/assistantDeepTurnInputBuilder.ts index 8f923f8..3427dc6 100644 --- a/llm_normalizer/backend/src/services/assistantDeepTurnInputBuilder.ts +++ b/llm_normalizer/backend/src/services/assistantDeepTurnInputBuilder.ts @@ -1,8 +1,34 @@ -import type { AssistantReplyType, AssistantRequirement, AnswerGroundingCheck, RequirementCoverageReport, UnifiedRetrievalResult } from "../types/assistant"; +import type { + AssistantAddressRuntimeMetaForDeep, + AssistantDebugRouteRecord, + AssistantExecutionStateRecord, + AssistantFallbackType, + AssistantProblemAnswerMode, + AssistantReplyType, + AssistantRequirement, + AnswerGroundingCheck, + FaLiveRouteAuditDebug, + RbpLiveRouteAuditDebug, + RequirementCoverageReport, + UnifiedRetrievalResult +} from "../types/assistant"; import type { NormalizeResponsePayload, RouteHintSummary } from "../types/normalizer"; import type { AnswerStructureV11 } from "../types/stage1Contracts"; +import type { InvestigationStateWithProblemUnits } from "../types/stage2ProblemUnits"; import type { AssistantDeepTurnPackagingInput } from "./assistantDeepTurnPackaging"; import type { AssistantFollowupUsage } from "./assistantFollowupUsage"; +import type { ClaimBoundAnchorAudit, TargetedEvidenceAcquisitionAudit } from "./assistantClaimBoundEvidence"; +import type { CompanyAnchorSet } from "./companyAnchorResolver"; +import type { + DomainPolarityGuardAudit, + EvidenceAdmissibilityAudit, + GroundedAnswerEligibilityAudit, + TemporalGuardAudit +} from "./assistantRuntimeGuards"; +import type { + AssistantRetrievalCallRecord, + AssistantRetrievalRawResultRecord +} from "./assistantDeepTurnRetrievalRuntimeAdapter"; export interface AssistantDeepTurnInputBuilderArgs { sessionId: string; @@ -36,13 +62,13 @@ export interface AssistantDeepTurnInputBuilderArgs { coverageEvaluationRequirements: AssistantRequirement[]; coverageReport: RequirementCoverageReport; groundingCheck: AnswerGroundingCheck; - retrievalCalls: Array>; - retrievalResultsRaw: unknown[]; + retrievalCalls: AssistantRetrievalCallRecord[]; + retrievalResultsRaw: AssistantRetrievalRawResultRecord[]; retrievalResults: UnifiedRetrievalResult[]; - routesForDebug: Array>; - resolvedExecutionState: unknown; + routesForDebug: AssistantDebugRouteRecord[]; + resolvedExecutionState: AssistantExecutionStateRecord[]; questionTypeClass: string; - companyAnchors: unknown; + companyAnchors: CompanyAnchorSet | null; runtimeAnalysisContext: { active: boolean; as_of_date: string | null; @@ -57,42 +83,29 @@ export interface AssistantDeepTurnInputBuilderArgs { company_grounding_applied?: boolean; scope_resolution_reason?: string[]; }; - temporalGuard: Record; - polarityAudit: Record; - claimAnchorAudit: Record; - targetedEvidenceAudit: unknown; - evidenceAdmissibilityGateAudit: unknown; - rbpLiveRouteAudit: unknown | null; - faLiveRouteAudit: unknown | null; - groundedAnswerEligibilityGuard: Record; + temporalGuard: TemporalGuardAudit; + polarityAudit: DomainPolarityGuardAudit; + claimAnchorAudit: ClaimBoundAnchorAudit; + targetedEvidenceAudit: TargetedEvidenceAcquisitionAudit; + evidenceAdmissibilityGateAudit: EvidenceAdmissibilityAudit; + rbpLiveRouteAudit: RbpLiveRouteAuditDebug | null; + faLiveRouteAudit: FaLiveRouteAuditDebug | null; + groundedAnswerEligibilityGuard: GroundedAnswerEligibilityAudit; followupStateUsage?: AssistantFollowupUsage | null; composition: { reply_type: AssistantReplyType; - fallback_type: unknown; + fallback_type: AssistantFallbackType; answer_structure_v11?: AnswerStructureV11 | null; problem_centric_answer_applied?: boolean; problem_units_used_count?: number; - problem_answer_mode?: string; - problem_unit_ids_used?: unknown; + problem_answer_mode?: AssistantProblemAnswerMode; + problem_unit_ids_used?: string[]; }; safeAssistantReplyBase: string; featureContractsV11: boolean; featureAnswerPolicyV11: boolean; - investigationStateSnapshot: unknown; - addressRuntimeMetaForDeep: - | { - attempted?: boolean; - applied?: boolean; - reason?: string | null; - provider?: string | null; - fallbackRuleHit?: string | null; - toolGateDecision?: string | null; - toolGateReason?: string | null; - predecomposeContract?: unknown; - orchestrationContract?: unknown; - } - | null - | undefined; + investigationStateSnapshot: InvestigationStateWithProblemUnits | null; + addressRuntimeMetaForDeep: AssistantAddressRuntimeMetaForDeep | null | undefined; } export function buildAssistantDeepTurnPackagingInput(args: AssistantDeepTurnInputBuilderArgs): AssistantDeepTurnPackagingInput { diff --git a/llm_normalizer/backend/src/services/assistantDeepTurnNormalizationRuntimeAdapter.ts b/llm_normalizer/backend/src/services/assistantDeepTurnNormalizationRuntimeAdapter.ts index d758c69..65c5416 100644 --- a/llm_normalizer/backend/src/services/assistantDeepTurnNormalizationRuntimeAdapter.ts +++ b/llm_normalizer/backend/src/services/assistantDeepTurnNormalizationRuntimeAdapter.ts @@ -1,5 +1,6 @@ import type { AssistantMessageRequestPayload } from "../types/assistant"; import type { NormalizeRequestPayload, NormalizeResponsePayload } from "../types/normalizer"; +import type { InvestigationStateWithProblemUnits } from "../types/stage2ProblemUnits"; import type { AssistantFollowupUsage } from "./assistantFollowupUsage"; export interface AssistantDeepTurnFollowupBinding { @@ -13,11 +14,11 @@ export interface BuildAssistantDeepTurnNormalizationRuntimeInput { payload: AssistantMessageRequestPayload; featureInvestigationStateV1: boolean; featureStateFollowupBindingV1: boolean; - sessionInvestigationState: unknown | null | undefined; + sessionInvestigationState: InvestigationStateWithProblemUnits | null | undefined; buildFollowupStateBinding: (input: { userMessage: string; payloadContext: NormalizeRequestPayload["context"] | undefined; - investigationState: unknown; + investigationState: InvestigationStateWithProblemUnits; }) => AssistantDeepTurnFollowupBinding; normalize: (payload: NormalizeRequestPayload) => Promise; } @@ -31,14 +32,18 @@ export interface BuildAssistantDeepTurnNormalizationRuntimeOutput { export async function buildAssistantDeepTurnNormalizationRuntime( input: BuildAssistantDeepTurnNormalizationRuntimeInput ): Promise { - const followupBinding = + const investigationState = input.sessionInvestigationState; + const canUseFollowupBinding = input.featureInvestigationStateV1 && input.featureStateFollowupBindingV1 && - Boolean(input.sessionInvestigationState) + investigationState !== null && + investigationState !== undefined; + const followupBinding = + canUseFollowupBinding ? input.buildFollowupStateBinding({ userMessage: input.userMessage, payloadContext: input.payload.context, - investigationState: input.sessionInvestigationState as unknown + investigationState }) : { normalizedQuestion: input.userMessage, diff --git a/llm_normalizer/backend/src/services/assistantDeepTurnPackaging.ts b/llm_normalizer/backend/src/services/assistantDeepTurnPackaging.ts index a041afe..2794554 100644 --- a/llm_normalizer/backend/src/services/assistantDeepTurnPackaging.ts +++ b/llm_normalizer/backend/src/services/assistantDeepTurnPackaging.ts @@ -1,14 +1,28 @@ import type { + AssistantAddressRuntimeMetaForDeep, AssistantConversationItem, AssistantDebugPayload, + AssistantDebugRouteRecord, + AssistantExecutionStateRecord, + AssistantFallbackType, + AssistantProblemAnswerMode, AssistantReplyType, AssistantRequirement, AnswerGroundingCheck, + FaLiveRouteAuditDebug, + RbpLiveRouteAuditDebug, RequirementCoverageReport, UnifiedRetrievalResult } from "../types/assistant"; -import type { NormalizeResponsePayload, RouteHintSummary } from "../types/normalizer"; +import type { + NormalizeResponsePayload, + NormalizedQueryV2, + NormalizedQueryV2_0_1, + NormalizedQueryV2_0_2, + RouteHintSummary +} from "../types/normalizer"; import type { AnswerStructureV11 } from "../types/stage1Contracts"; +import type { InvestigationStateWithProblemUnits } from "../types/stage2ProblemUnits"; import { assembleAssistantEvidenceBundle, type AssistantEvidenceBundleAssembly @@ -16,8 +30,23 @@ import { import { assembleAssistantContractsBundleV1, type AssistantContractsBundleV1 } from "./assistantContractsBundleAssembler"; import { buildDeepAnswerArtifacts, buildAssistantConversationItem, type DeepAnswerArtifacts } from "./assistantDeepResponseAssembler"; import { buildDeepAnalysisDebugPayload } from "./assistantDebugPayloadAssembler"; -import { buildDeepAnalysisProcessedLogDetails } from "./assistantMessageLogAssembler"; +import { + buildDeepAnalysisProcessedLogDetails, + type DeepAnalysisLogDetails +} from "./assistantMessageLogAssembler"; import type { AssistantFollowupUsage } from "./assistantFollowupUsage"; +import type { ClaimBoundAnchorAudit, TargetedEvidenceAcquisitionAudit } from "./assistantClaimBoundEvidence"; +import type { CompanyAnchorSet } from "./companyAnchorResolver"; +import type { + DomainPolarityGuardAudit, + EvidenceAdmissibilityAudit, + GroundedAnswerEligibilityAudit, + TemporalGuardAudit +} from "./assistantRuntimeGuards"; +import type { + AssistantRetrievalCallRecord, + AssistantRetrievalRawResultRecord +} from "./assistantDeepTurnRetrievalRuntimeAdapter"; export interface AssistantDeepTurnPackagingInput { sessionId: string; @@ -51,13 +80,13 @@ export interface AssistantDeepTurnPackagingInput { coverageEvaluationRequirements: AssistantRequirement[]; coverageReport: RequirementCoverageReport; groundingCheck: AnswerGroundingCheck; - retrievalCalls: Array>; - retrievalResultsRaw: unknown[]; + retrievalCalls: AssistantRetrievalCallRecord[]; + retrievalResultsRaw: AssistantRetrievalRawResultRecord[]; retrievalResults: UnifiedRetrievalResult[]; - routesForDebug: Array>; - resolvedExecutionState: unknown; + routesForDebug: AssistantDebugRouteRecord[]; + resolvedExecutionState: AssistantExecutionStateRecord[]; questionTypeClass: string; - companyAnchors: unknown; + companyAnchors: CompanyAnchorSet | null; runtimeAnalysisContext: { active: boolean; as_of_date: string | null; @@ -72,42 +101,29 @@ export interface AssistantDeepTurnPackagingInput { company_grounding_applied?: boolean; scope_resolution_reason?: string[]; }; - temporalGuard: Record; - polarityAudit: Record; - claimAnchorAudit: Record; - targetedEvidenceAudit: unknown; - evidenceAdmissibilityGateAudit: unknown; - rbpLiveRouteAudit: unknown | null; - faLiveRouteAudit: unknown | null; - groundedAnswerEligibilityGuard: Record; + temporalGuard: TemporalGuardAudit; + polarityAudit: DomainPolarityGuardAudit; + claimAnchorAudit: ClaimBoundAnchorAudit; + targetedEvidenceAudit: TargetedEvidenceAcquisitionAudit; + evidenceAdmissibilityGateAudit: EvidenceAdmissibilityAudit; + rbpLiveRouteAudit: RbpLiveRouteAuditDebug | null; + faLiveRouteAudit: FaLiveRouteAuditDebug | null; + groundedAnswerEligibilityGuard: GroundedAnswerEligibilityAudit; followupStateUsage: AssistantFollowupUsage | null; composition: { reply_type: AssistantReplyType; - fallback_type: unknown; + fallback_type: AssistantFallbackType; answer_structure_v11?: AnswerStructureV11 | null; problem_centric_answer_applied?: boolean; problem_units_used_count?: number; - problem_answer_mode?: string; + problem_answer_mode?: AssistantProblemAnswerMode; problem_unit_ids_used?: string[]; }; safeAssistantReplyBase: string; featureContractsV11: boolean; featureAnswerPolicyV11: boolean; - investigationStateSnapshot: unknown; - addressRuntimeMetaForDeep: - | { - attempted?: boolean; - applied?: boolean; - reason?: string | null; - provider?: string | null; - fallbackRuleHit?: string | null; - toolGateDecision?: string | null; - toolGateReason?: string | null; - predecomposeContract?: unknown; - orchestrationContract?: unknown; - } - | null - | undefined; + investigationStateSnapshot: InvestigationStateWithProblemUnits | null; + addressRuntimeMetaForDeep: AssistantAddressRuntimeMetaForDeep | null | undefined; } export interface AssistantDeepTurnPackagingOutput { @@ -116,12 +132,25 @@ export interface AssistantDeepTurnPackagingOutput { deepAnswerArtifacts: DeepAnswerArtifacts; debug: AssistantDebugPayload; assistantItem: AssistantConversationItem; - deepAnalysisLogDetails: Record; + deepAnalysisLogDetails: DeepAnalysisLogDetails; +} + +type NormalizedFragments = + | NormalizedQueryV2["fragments"] + | NormalizedQueryV2_0_1["fragments"] + | NormalizedQueryV2_0_2["fragments"]; + +function extractNormalizedFragments(normalized: NormalizeResponsePayload["normalized"] | null): NormalizedFragments { + if (!normalized || typeof normalized !== "object") { + return []; + } + const source = normalized as NormalizedQueryV2 | NormalizedQueryV2_0_1 | NormalizedQueryV2_0_2; + return Array.isArray(source.fragments) ? source.fragments : []; } export function assembleAssistantDeepTurnPackaging(input: AssistantDeepTurnPackagingInput): AssistantDeepTurnPackagingOutput { - const normalizedPayload = (input.normalized.normalized ?? null) as Record | null; - const normalizedFragments = Array.isArray(normalizedPayload?.["fragments"]) ? (normalizedPayload?.["fragments"] as unknown[]) : []; + const normalizedPayload = input.normalized.normalized ?? null; + const normalizedFragments = extractNormalizedFragments(normalizedPayload); const evidenceBundleAssembly = assembleAssistantEvidenceBundle({ retrievalCalls: input.retrievalCalls, retrievalResults: input.retrievalResults @@ -232,7 +261,7 @@ export function assembleAssistantDeepTurnPackaging(input: AssistantDeepTurnPacka problem_units_used_count: input.composition.problem_units_used_count ?? 0, problem_answer_mode: input.composition.problem_answer_mode ?? "stage1_policy_v11", problem_unit_ids_used: Array.isArray(input.composition.problem_unit_ids_used) ? input.composition.problem_unit_ids_used : [], - fallback_type: input.composition.fallback_type as string + fallback_type: input.composition.fallback_type }, outcomeClassV1: contractsBundleV1.outcomeClassV1, assistantOrchestrationContractsV1: contractsBundleV1.assistantOrchestrationContractsV1, diff --git a/llm_normalizer/backend/src/services/assistantDeepTurnPackagingRuntimeAdapter.ts b/llm_normalizer/backend/src/services/assistantDeepTurnPackagingRuntimeAdapter.ts index c27bb12..71c054c 100644 --- a/llm_normalizer/backend/src/services/assistantDeepTurnPackagingRuntimeAdapter.ts +++ b/llm_normalizer/backend/src/services/assistantDeepTurnPackagingRuntimeAdapter.ts @@ -1,9 +1,14 @@ import { nanoid } from "nanoid"; import type { + AssistantAddressRuntimeMetaForDeep, AssistantConversationItem, AssistantDebugPayload, + AssistantDebugRouteRecord, + AssistantExecutionStateRecord, AssistantRequirement, AnswerGroundingCheck, + FaLiveRouteAuditDebug, + RbpLiveRouteAuditDebug, RequirementCoverageReport, UnifiedRetrievalResult } from "../types/assistant"; @@ -13,6 +18,18 @@ import type { AssistantDeepTurnInputBuilderArgs } from "./assistantDeepTurnInput import { buildAssistantDeepTurnPackagingInput } from "./assistantDeepTurnInputBuilder"; import { assembleAssistantDeepTurnPackaging } from "./assistantDeepTurnPackaging"; import type { AssistantFollowupUsage } from "./assistantFollowupUsage"; +import type { ClaimBoundAnchorAudit, TargetedEvidenceAcquisitionAudit } from "./assistantClaimBoundEvidence"; +import type { CompanyAnchorSet } from "./companyAnchorResolver"; +import type { + DomainPolarityGuardAudit, + EvidenceAdmissibilityAudit, + GroundedAnswerEligibilityAudit, + TemporalGuardAudit +} from "./assistantRuntimeGuards"; +import type { + AssistantRetrievalCallRecord, + AssistantRetrievalRawResultRecord +} from "./assistantDeepTurnRetrievalRuntimeAdapter"; import type { AssistantAnalysisContextForContract, AssistantRuntimeAnalysisContextForPrePackaging @@ -22,6 +39,7 @@ import { buildAssistantInvestigationStateSnapshot, persistAssistantInvestigationStateSnapshot } from "./assistantInvestigationStateRuntimeAdapter"; +import type { DeepAnalysisLogDetails } from "./assistantMessageLogAssembler"; type AssistantDeepTurnCompositionForPackaging = AssistantDeepTurnInputBuilderArgs["composition"] & { assistant_reply: string; @@ -45,44 +63,31 @@ export interface AssistantDeepTurnPackagingRuntimeInput { coverageEvaluationRequirements: AssistantRequirement[]; coverageReport: RequirementCoverageReport; groundingCheck: AnswerGroundingCheck; - retrievalCalls: Array>; - retrievalResultsRaw: unknown[]; + retrievalCalls: AssistantRetrievalCallRecord[]; + retrievalResultsRaw: AssistantRetrievalRawResultRecord[]; retrievalResults: UnifiedRetrievalResult[]; questionTypeClass: string; - companyAnchors: unknown; + companyAnchors: CompanyAnchorSet | null; runtimeAnalysisContext: AssistantDeepTurnInputBuilderArgs["runtimeAnalysisContext"]; businessScopeResolution: AssistantDeepTurnInputBuilderArgs["businessScopeResolution"]; - temporalGuard: Record; - polarityAudit: Record; - claimAnchorAudit: Record; - targetedEvidenceAudit: unknown; - evidenceAdmissibilityGateAudit: unknown; - rbpLiveRouteAudit: unknown | null; - faLiveRouteAudit: unknown | null; - groundedAnswerEligibilityGuard: Record; + temporalGuard: TemporalGuardAudit; + polarityAudit: DomainPolarityGuardAudit; + claimAnchorAudit: ClaimBoundAnchorAudit; + targetedEvidenceAudit: TargetedEvidenceAcquisitionAudit; + evidenceAdmissibilityGateAudit: EvidenceAdmissibilityAudit; + rbpLiveRouteAudit: RbpLiveRouteAuditDebug | null; + faLiveRouteAudit: FaLiveRouteAuditDebug | null; + groundedAnswerEligibilityGuard: GroundedAnswerEligibilityAudit; followupStateUsage?: AssistantFollowupUsage | null; followupApplied: boolean; composition: AssistantDeepTurnCompositionForPackaging; featureContractsV11: boolean; featureAnswerPolicyV11: boolean; previousInvestigationState: InvestigationStateWithProblemUnits | null | undefined; - addressRuntimeMetaForDeep: - | { - attempted?: boolean; - applied?: boolean; - reason?: string | null; - provider?: string | null; - fallbackRuleHit?: string | null; - toolGateDecision?: string | null; - toolGateReason?: string | null; - predecomposeContract?: unknown; - orchestrationContract?: unknown; - } - | null - | undefined; + addressRuntimeMetaForDeep: AssistantAddressRuntimeMetaForDeep | null | undefined; extractDroppedIntentSegments: (normalizedPayload: NormalizeResponsePayload["normalized"]) => string[]; - buildDebugRoutes: (routeSummary: RouteHintSummary | null) => Array>; - extractExecutionState: (normalizedPayload: NormalizeResponsePayload["normalized"]) => unknown; + buildDebugRoutes: (routeSummary: RouteHintSummary | null) => AssistantDebugRouteRecord[]; + extractExecutionState: (normalizedPayload: NormalizeResponsePayload["normalized"]) => AssistantExecutionStateRecord[]; sanitizeReply: (value: string, fallback?: string) => string; persistInvestigationState: (sessionId: string, snapshot: InvestigationStateWithProblemUnits) => void; nowIso?: () => string; @@ -99,13 +104,13 @@ export interface AssistantDeepTurnPackagingRuntimeOutput { investigationStateSnapshot: InvestigationStateWithProblemUnits | null; droppedIntentSegments: string[]; analysisContextForContract: AssistantAnalysisContextForContract | null; - routesForDebug: Array>; - resolvedExecutionState: unknown; + routesForDebug: AssistantDebugRouteRecord[]; + resolvedExecutionState: AssistantExecutionStateRecord[]; safeAssistantReplyBase: string; safeAssistantReply: string; debug: AssistantDebugPayload; assistantItem: AssistantConversationItem; - deepAnalysisLogDetails: Record; + deepAnalysisLogDetails: DeepAnalysisLogDetails; } export function runAssistantDeepTurnPackagingRuntime( diff --git a/llm_normalizer/backend/src/services/assistantDeepTurnPlanRuntimeAdapter.ts b/llm_normalizer/backend/src/services/assistantDeepTurnPlanRuntimeAdapter.ts index 94d0580..0cc02ad 100644 --- a/llm_normalizer/backend/src/services/assistantDeepTurnPlanRuntimeAdapter.ts +++ b/llm_normalizer/backend/src/services/assistantDeepTurnPlanRuntimeAdapter.ts @@ -1,6 +1,7 @@ import type { AssistantRequirement } from "../types/assistant"; import type { NormalizeResponsePayload, RouteHintSummary } from "../types/normalizer"; import type { AssistantExecutionPlanItem } from "./assistantQueryPlanning"; +import type { DomainPolarityGuardAudit, TemporalGuardAudit } from "./assistantRuntimeGuards"; export interface AssistantRequirementExtractionLike { requirements: AssistantRequirement[]; @@ -9,7 +10,15 @@ export interface AssistantRequirementExtractionLike { export interface AssistantPlanEnforcementAuditLike { executionPlan: AssistantExecutionPlanItem[]; - audit: Record | null; + audit: AssistantLiveRoutePlanAudit | null; +} + +export interface AssistantLiveRoutePlanAudit extends Record { + required_live_calls: string[]; + route_adjustments_applied: number; + rescued_no_route_fragments: number; + replaced_routes: string[]; + route_gap_reason: string | null; } export interface BuildAssistantDeepTurnExecutionPlanInput { @@ -17,8 +26,8 @@ export interface BuildAssistantDeepTurnExecutionPlanInput { normalizedPayload: NormalizeResponsePayload["normalized"]; userMessage: string; claimType: string; - temporalGuard: unknown; - domainPolarityGuardInitial: unknown; + temporalGuard: TemporalGuardAudit; + domainPolarityGuardInitial: DomainPolarityGuardAudit; extractRequirements: ( routeSummary: RouteHintSummary | null, normalizedPayload: NormalizeResponsePayload["normalized"], @@ -33,20 +42,20 @@ export interface BuildAssistantDeepTurnExecutionPlanInput { enforceRbpLiveRoutePlan: (input: { executionPlan: AssistantExecutionPlanItem[]; claimType: string; - temporalGuard: unknown; + temporalGuard: TemporalGuardAudit; }) => AssistantPlanEnforcementAuditLike; enforceFaLiveRoutePlan: (input: { executionPlan: AssistantExecutionPlanItem[]; claimType: string; - temporalGuard: unknown; + temporalGuard: TemporalGuardAudit; }) => AssistantPlanEnforcementAuditLike; applyTemporalHintToExecutionPlan: ( executionPlan: AssistantExecutionPlanItem[], - temporalGuard: unknown + temporalGuard: TemporalGuardAudit ) => AssistantExecutionPlanItem[]; applyPolarityHintToExecutionPlan: ( executionPlan: AssistantExecutionPlanItem[], - domainPolarityGuardInitial: unknown + domainPolarityGuardInitial: DomainPolarityGuardAudit ) => AssistantExecutionPlanItem[]; } diff --git a/llm_normalizer/backend/src/services/assistantDeepTurnPrePackagingContext.ts b/llm_normalizer/backend/src/services/assistantDeepTurnPrePackagingContext.ts index fd74aa3..f047dca 100644 --- a/llm_normalizer/backend/src/services/assistantDeepTurnPrePackagingContext.ts +++ b/llm_normalizer/backend/src/services/assistantDeepTurnPrePackagingContext.ts @@ -1,4 +1,5 @@ import type { NormalizeResponsePayload, RouteHintSummary } from "../types/normalizer"; +import type { AssistantDebugRouteRecord, AssistantExecutionStateRecord } from "../types/assistant"; export interface AssistantRuntimeAnalysisContextForPrePackaging { active: boolean; @@ -23,16 +24,16 @@ export interface BuildAssistantDeepTurnPrePackagingContextInput { runtimeAnalysisContext: AssistantRuntimeAnalysisContextForPrePackaging; assistantReply: string; extractDroppedIntentSegments: (normalizedPayload: NormalizeResponsePayload["normalized"]) => string[]; - buildDebugRoutes: (routeSummary: RouteHintSummary | null) => Array>; - extractExecutionState: (normalizedPayload: NormalizeResponsePayload["normalized"]) => unknown; + buildDebugRoutes: (routeSummary: RouteHintSummary | null) => AssistantDebugRouteRecord[]; + extractExecutionState: (normalizedPayload: NormalizeResponsePayload["normalized"]) => AssistantExecutionStateRecord[]; sanitizeReply: (value: string, fallback?: string) => string; } export interface AssistantDeepTurnPrePackagingContext { droppedIntentSegments: string[]; analysisContextForContract: AssistantAnalysisContextForContract | null; - routesForDebug: Array>; - resolvedExecutionState: unknown; + routesForDebug: AssistantDebugRouteRecord[]; + resolvedExecutionState: AssistantExecutionStateRecord[]; safeAssistantReplyBase: string; } diff --git a/llm_normalizer/backend/src/services/assistantDeepTurnResponseRuntimeAdapter.ts b/llm_normalizer/backend/src/services/assistantDeepTurnResponseRuntimeAdapter.ts index abe911e..9982cce 100644 --- a/llm_normalizer/backend/src/services/assistantDeepTurnResponseRuntimeAdapter.ts +++ b/llm_normalizer/backend/src/services/assistantDeepTurnResponseRuntimeAdapter.ts @@ -1,4 +1,12 @@ -import type { AssistantDebugPayload, AssistantMessageResponsePayload } from "../types/assistant"; +import type { + AssistantAddressRuntimeMetaForDeep, + AssistantDebugPayload, + AssistantDebugRouteRecord, + AssistantExecutionStateRecord, + AssistantMessageResponsePayload, + FaLiveRouteAuditDebug, + RbpLiveRouteAuditDebug +} from "../types/assistant"; import type { NormalizeResponsePayload, RouteHintSummary } from "../types/normalizer"; import type { InvestigationStateWithProblemUnits } from "../types/stage2ProblemUnits"; import { @@ -7,10 +15,23 @@ import { type AssistantDeepTurnPackagingRuntimeOutput } from "./assistantDeepTurnPackagingRuntimeAdapter"; import type { RunAssistantDeepTurnAnalysisRuntimeOutput } from "./assistantDeepTurnAnalysisRuntimeAdapter"; +import type { AssistantExecutionPlanItem } from "./assistantQueryPlanning"; import { finalizeAssistantDeepTurn, type FinalizeAssistantDeepTurnInput } from "./assistantDeepTurnFinalizeRuntimeAdapter"; +import type { ClaimBoundAnchorAudit, TargetedEvidenceAcquisitionAudit } from "./assistantClaimBoundEvidence"; +import type { CompanyAnchorSet } from "./companyAnchorResolver"; +import type { + DomainPolarityGuardAudit, + EvidenceAdmissibilityAudit, + GroundedAnswerEligibilityAudit, + TemporalGuardAudit +} from "./assistantRuntimeGuards"; +import type { + AssistantRetrievalCallRecord, + AssistantRetrievalRawResultRecord +} from "./assistantDeepTurnRetrievalRuntimeAdapter"; export interface RunAssistantDeepTurnResponseRuntimeInput { featureInvestigationStateV1: boolean; @@ -27,16 +48,16 @@ export interface RunAssistantDeepTurnResponseRuntimeInput { }; normalizedQuestion: string; routeSummary: RouteHintSummary | null; - executionPlan: unknown[]; + executionPlan: AssistantExecutionPlanItem[]; requirementExtractionRequirements: AssistantDeepTurnPackagingRuntimeInput["requirementExtractionRequirements"]; coverageEvaluationRequirements: AssistantDeepTurnPackagingRuntimeInput["coverageEvaluationRequirements"]; coverageReport: AssistantDeepTurnPackagingRuntimeInput["coverageReport"]; groundingCheck: AssistantDeepTurnPackagingRuntimeInput["groundingCheck"]; - retrievalCalls: unknown[]; - retrievalResultsRaw: unknown[]; + retrievalCalls: AssistantRetrievalCallRecord[]; + retrievalResultsRaw: AssistantRetrievalRawResultRecord[]; retrievalResults: AssistantDeepTurnPackagingRuntimeInput["retrievalResults"]; questionTypeClass: AssistantDeepTurnPackagingRuntimeInput["questionTypeClass"]; - companyAnchors: RunAssistantDeepTurnAnalysisRuntimeOutput["companyAnchors"]; + companyAnchors: CompanyAnchorSet | null; runtimeAnalysisContext: { active: boolean; as_of_date: string | null; @@ -46,22 +67,22 @@ export interface RunAssistantDeepTurnResponseRuntimeInput { snapshot_mode?: "auto" | "force_snapshot" | "force_live"; }; businessScopeResolution: RunAssistantDeepTurnAnalysisRuntimeOutput["businessScopeResolution"]; - temporalGuard: unknown; - polarityAudit: unknown; - claimAnchorAudit: unknown; - targetedEvidenceAudit: unknown; - evidenceAdmissibilityGateAudit: unknown; - rbpLiveRouteAudit: unknown; - faLiveRouteAudit: unknown; - groundedAnswerEligibilityGuard: unknown; + temporalGuard: TemporalGuardAudit; + polarityAudit: DomainPolarityGuardAudit; + claimAnchorAudit: ClaimBoundAnchorAudit; + targetedEvidenceAudit: TargetedEvidenceAcquisitionAudit; + evidenceAdmissibilityGateAudit: EvidenceAdmissibilityAudit; + rbpLiveRouteAudit: RbpLiveRouteAuditDebug | null; + faLiveRouteAudit: FaLiveRouteAuditDebug | null; + groundedAnswerEligibilityGuard: GroundedAnswerEligibilityAudit; followupStateUsage: AssistantDeepTurnPackagingRuntimeInput["followupStateUsage"]; followupApplied: boolean; composition: AssistantDeepTurnPackagingRuntimeInput["composition"]; previousInvestigationState: AssistantDeepTurnPackagingRuntimeInput["previousInvestigationState"]; addressRuntimeMetaForDeep: AssistantDeepTurnPackagingRuntimeInput["addressRuntimeMetaForDeep"]; extractDroppedIntentSegments: (normalizedPayload: NormalizeResponsePayload["normalized"]) => string[]; - buildDebugRoutes: (routeSummary: RouteHintSummary | null) => Array>; - extractExecutionState: (normalizedPayload: NormalizeResponsePayload["normalized"]) => unknown[]; + buildDebugRoutes: (routeSummary: RouteHintSummary | null) => AssistantDebugRouteRecord[]; + extractExecutionState: (normalizedPayload: NormalizeResponsePayload["normalized"]) => AssistantExecutionStateRecord[]; sanitizeReply: (value: string, fallback?: string) => string; persistInvestigationState: (sessionId: string, snapshot: InvestigationStateWithProblemUnits) => void; messageIdFactory: () => string; @@ -81,14 +102,7 @@ export interface RunAssistantDeepTurnResponseRuntimeOutput { debug: AssistantDebugPayload; } -function toRecordObject(value: unknown): Record | null { - if (!value || typeof value !== "object") { - return null; - } - return value as Record; -} - -function toNullableString(value: unknown): string | null { +function toNullableString(value: string | null | undefined): string | null { if (typeof value !== "string") { return null; } @@ -96,7 +110,7 @@ function toNullableString(value: unknown): string | null { return trimmed.length > 0 ? trimmed : null; } -function toStringArray(value: unknown): string[] { +function toStringArray(value: string[] | null | undefined): string[] { if (!Array.isArray(value)) { return []; } @@ -105,44 +119,30 @@ function toStringArray(value: unknown): string[] { .filter((item) => item.length > 0); } -function toSnapshotMode(value: unknown): "auto" | "force_snapshot" | "force_live" { +function toSnapshotMode(value: string | null | undefined): "auto" | "force_snapshot" | "force_live" { return value === "force_snapshot" || value === "force_live" ? value : "auto"; } -function normalizeExecutionPlan(value: unknown[]): AssistantDeepTurnPackagingRuntimeInput["executionPlan"] { +function normalizeExecutionPlan( + value: AssistantExecutionPlanItem[] +): AssistantDeepTurnPackagingRuntimeInput["executionPlan"] { if (!Array.isArray(value)) { return []; } - return value.map((item, index) => { - const source = toRecordObject(item); - return { - fragment_id: toNullableString(source?.fragment_id) ?? `fragment_${index + 1}`, - requirement_ids: toStringArray(source?.requirement_ids), - route: toNullableString(source?.route) ?? "unknown_route", - should_execute: Boolean(source?.should_execute), - no_route_reason: toNullableString(source?.no_route_reason), - clarification_reason: toNullableString(source?.clarification_reason) - }; - }); -} - -function normalizeRecordArray(value: unknown[]): Array> { - if (!Array.isArray(value)) { - return []; - } - return value - .map((item) => toRecordObject(item)) - .filter((item): item is Record => Boolean(item)); -} - -function normalizeRecord(value: unknown): Record { - return toRecordObject(value) ?? {}; + return value.map((item, index) => ({ + fragment_id: toNullableString(item.fragment_id) ?? `fragment_${index + 1}`, + requirement_ids: toStringArray(item.requirement_ids), + route: toNullableString(item.route) ?? "unknown_route", + should_execute: Boolean(item.should_execute), + no_route_reason: toNullableString(item.no_route_reason ?? null), + clarification_reason: toNullableString(item.clarification_reason ?? null) + })); } function normalizeRuntimeAnalysisContext( - value: unknown + value: RunAssistantDeepTurnResponseRuntimeInput["runtimeAnalysisContext"] | null | undefined ): AssistantDeepTurnPackagingRuntimeInput["runtimeAnalysisContext"] { - const source = toRecordObject(value); + const source = value; return { active: Boolean(source?.active), as_of_date: toNullableString(source?.as_of_date), @@ -154,9 +154,9 @@ function normalizeRuntimeAnalysisContext( } function normalizeBusinessScopeResolution( - value: unknown + value: RunAssistantDeepTurnAnalysisRuntimeOutput["businessScopeResolution"] | null | undefined ): AssistantDeepTurnPackagingRuntimeInput["businessScopeResolution"] { - const source = toRecordObject(value); + const source = value; return { business_scope_raw: toStringArray(source?.business_scope_raw), business_scope_resolved: toStringArray(source?.business_scope_resolved), @@ -166,9 +166,9 @@ function normalizeBusinessScopeResolution( } function normalizeAddressRuntimeMetaForDeep( - value: unknown -): AssistantDeepTurnPackagingRuntimeInput["addressRuntimeMetaForDeep"] { - const source = toRecordObject(value); + value: AssistantAddressRuntimeMetaForDeep | null | undefined +): AssistantAddressRuntimeMetaForDeep | null { + const source = value; if (!source) { return null; } @@ -180,8 +180,8 @@ function normalizeAddressRuntimeMetaForDeep( fallbackRuleHit: toNullableString(source.fallbackRuleHit), toolGateDecision: toNullableString(source.toolGateDecision), toolGateReason: toNullableString(source.toolGateReason), - predecomposeContract: toRecordObject(source.predecomposeContract), - orchestrationContract: toRecordObject(source.orchestrationContract) + predecomposeContract: source.predecomposeContract ?? null, + orchestrationContract: source.orchestrationContract ?? null }; } @@ -204,21 +204,21 @@ export function runAssistantDeepTurnResponseRuntime( coverageEvaluationRequirements: input.coverageEvaluationRequirements, coverageReport: input.coverageReport, groundingCheck: input.groundingCheck, - retrievalCalls: normalizeRecordArray(input.retrievalCalls), - retrievalResultsRaw: Array.isArray(input.retrievalResultsRaw) ? input.retrievalResultsRaw : [], + retrievalCalls: input.retrievalCalls, + retrievalResultsRaw: input.retrievalResultsRaw, retrievalResults: input.retrievalResults, questionTypeClass: input.questionTypeClass, companyAnchors: input.companyAnchors, runtimeAnalysisContext: normalizeRuntimeAnalysisContext(input.runtimeAnalysisContext), businessScopeResolution: normalizeBusinessScopeResolution(input.businessScopeResolution), - temporalGuard: normalizeRecord(input.temporalGuard), - polarityAudit: normalizeRecord(input.polarityAudit), - claimAnchorAudit: normalizeRecord(input.claimAnchorAudit), + temporalGuard: input.temporalGuard, + polarityAudit: input.polarityAudit, + claimAnchorAudit: input.claimAnchorAudit, targetedEvidenceAudit: input.targetedEvidenceAudit, evidenceAdmissibilityGateAudit: input.evidenceAdmissibilityGateAudit, rbpLiveRouteAudit: input.rbpLiveRouteAudit ?? null, faLiveRouteAudit: input.faLiveRouteAudit ?? null, - groundedAnswerEligibilityGuard: normalizeRecord(input.groundedAnswerEligibilityGuard), + groundedAnswerEligibilityGuard: input.groundedAnswerEligibilityGuard, followupStateUsage: input.followupStateUsage, followupApplied: input.followupApplied, composition: input.composition, diff --git a/llm_normalizer/backend/src/services/assistantDeepTurnRetrievalRuntimeAdapter.ts b/llm_normalizer/backend/src/services/assistantDeepTurnRetrievalRuntimeAdapter.ts index acaac03..757d2ad 100644 --- a/llm_normalizer/backend/src/services/assistantDeepTurnRetrievalRuntimeAdapter.ts +++ b/llm_normalizer/backend/src/services/assistantDeepTurnRetrievalRuntimeAdapter.ts @@ -18,10 +18,43 @@ export interface AssistantRetrievalCallRecord { reason: string | null; } +export type AssistantRetrievalScalar = string | number | boolean | null; +export type AssistantRetrievalFieldValue = + | AssistantRetrievalScalar + | AssistantRetrievalFieldValue[] + | { [key: string]: AssistantRetrievalFieldValue }; +export type AssistantRetrievalRecord = Record; + +export interface AssistantRetrievalRawResultLike { + status: "ok" | "empty" | "partial" | "error"; + result_type: "list" | "summary" | "object" | "chain" | "ranking"; + items: AssistantRetrievalRecord[]; + summary: AssistantRetrievalRecord; + evidence: AssistantRetrievalRecord[]; + why_included: string[]; + selection_reason: string[]; + risk_factors: string[]; + business_interpretation: string[]; + confidence: "high" | "medium" | "low"; + limitations: string[]; + errors: string[]; +} + +export type AssistantRetrievalRawListItem = AssistantRetrievalFieldValue; +export type AssistantRetrievalRawList = AssistantRetrievalFieldValue[]; + +export type AssistantRetrievalRawResult = + | AssistantRetrievalRawResultLike + | AssistantRetrievalRawList + | string + | number + | boolean + | null; + export interface AssistantRetrievalRawResultRecord { fragment_id: string; route: string; - raw_result: unknown; + raw_result: AssistantRetrievalRawResult; } export interface AssistantDeepTurnRetrievalExecutionInput { @@ -33,7 +66,7 @@ export interface AssistantDeepTurnRetrievalExecutionInput { options: { temporalHint: AssistantLiveTemporalHint | null; } - ) => Promise; + ) => Promise; mapNoRouteReason: (reason: string | null) => string; buildSkippedResult: (item: AssistantExecutionPlanItem) => UnifiedRetrievalResult; normalizeRetrievalResultFn?: typeof normalizeRetrievalResult; @@ -45,7 +78,7 @@ export interface AssistantDeepTurnRetrievalExecutionOutput { retrievalResults: UnifiedRetrievalResult[]; } -function buildRouteExecutorErrorRawResult(route: string, message: string): Record { +function buildRouteExecutorErrorRawResult(route: string, message: string): AssistantRetrievalRawResult { return { status: "error", result_type: "summary", @@ -64,6 +97,24 @@ function buildRouteExecutorErrorRawResult(route: string, message: string): Recor }; } +function normalizeRawResult( + value: AssistantRetrievalRawResult | object | null | undefined +): AssistantRetrievalRawResult { + if (value === null || value === undefined) { + return null; + } + if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") { + return value; + } + if (Array.isArray(value)) { + return value as AssistantRetrievalRawList; + } + if (typeof value === "object") { + return value as AssistantRetrievalRawResultLike; + } + return null; +} + export async function executeAssistantDeepTurnRetrievalPlan( input: AssistantDeepTurnRetrievalExecutionInput ): Promise { @@ -99,13 +150,14 @@ export async function executeAssistantDeepTurnRetrievalPlan( const raw = await input.executeRouteRuntime(planItem.route, planItem.fragment_text, { temporalHint: input.liveTemporalHint }); + const normalizedRaw = normalizeRawResult(raw); retrievalResultsRaw.push({ fragment_id: planItem.fragment_id, route: planItem.route, - raw_result: raw + raw_result: normalizedRaw }); retrievalResults.push( - normalizeRetrievalResultSafe(planItem.fragment_id, planItem.requirement_ids, planItem.route, raw) + normalizeRetrievalResultSafe(planItem.fragment_id, planItem.requirement_ids, planItem.route, normalizedRaw) ); } catch (error) { const message = error instanceof Error ? error.message : String(error); diff --git a/llm_normalizer/backend/src/services/assistantEvidenceBundleAssembler.ts b/llm_normalizer/backend/src/services/assistantEvidenceBundleAssembler.ts index 70a6116..4bafc18 100644 --- a/llm_normalizer/backend/src/services/assistantEvidenceBundleAssembler.ts +++ b/llm_normalizer/backend/src/services/assistantEvidenceBundleAssembler.ts @@ -3,6 +3,7 @@ import { buildAssistantEvidenceBundleContractV1, type AssistantEvidenceBundleContractV1 } from "./assistantOrchestrationContracts"; +import type { AssistantRetrievalCallRecord } from "./assistantDeepTurnRetrievalRuntimeAdapter"; type RetrievalStatusItem = AssistantDebugPayload["retrieval_status"][number]; @@ -22,7 +23,7 @@ function buildRetrievalStatus(retrievalResults: UnifiedRetrievalResult[]): Retri } export function assembleAssistantEvidenceBundle(input: { - retrievalCalls: Array>; + retrievalCalls: AssistantRetrievalCallRecord[]; retrievalResults: UnifiedRetrievalResult[]; }): AssistantEvidenceBundleAssembly { const retrievalResults = Array.isArray(input.retrievalResults) ? input.retrievalResults : []; diff --git a/llm_normalizer/backend/src/services/assistantMessageLogAssembler.ts b/llm_normalizer/backend/src/services/assistantMessageLogAssembler.ts index 5882047..af51cf5 100644 --- a/llm_normalizer/backend/src/services/assistantMessageLogAssembler.ts +++ b/llm_normalizer/backend/src/services/assistantMessageLogAssembler.ts @@ -1,4 +1,33 @@ -import type { AnswerGroundingCheck, RequirementCoverageReport } from "../types/assistant"; +import type { + AssistantDebugRouteRecord, + AssistantExecutionStateRecord, + AssistantFallbackType, + AssistantProblemAnswerMode, + AssistantReplyType, + AssistantRequirement, + UnifiedRetrievalResult, + AnswerGroundingCheck, + FaLiveRouteAuditDebug, + RbpLiveRouteAuditDebug, + RequirementCoverageReport +} from "../types/assistant"; +import type { AnswerStructureV11 } from "../types/stage1Contracts"; +import type { InvestigationStateWithProblemUnits } from "../types/stage2ProblemUnits"; +import type { ClaimBoundAnchorAudit, TargetedEvidenceAcquisitionAudit } from "./assistantClaimBoundEvidence"; +import type { AssistantContractsBundleV1 } from "./assistantContractsBundleAssembler"; +import type { AssistantOutcomeClassV1 } from "./assistantOrchestrationContracts"; +import type { AssistantFollowupUsage } from "./assistantFollowupUsage"; +import type { CompanyAnchorSet } from "./companyAnchorResolver"; +import type { + AssistantRetrievalCallRecord, + AssistantRetrievalRawResultRecord +} from "./assistantDeepTurnRetrievalRuntimeAdapter"; +import type { + DomainPolarityGuardAudit, + EvidenceAdmissibilityAudit, + GroundedAnswerEligibilityAudit, + TemporalGuardAudit +} from "./assistantRuntimeGuards"; export interface DeepAnalysisMessageLogDetailsInput { sessionId: string; @@ -6,18 +35,18 @@ export interface DeepAnalysisMessageLogDetailsInput { userMessage: string; normalizerOutput: unknown; executionPlan: Array>; - resolvedExecutionState: unknown; - routes: Array>; - retrievalCalls: Array>; - retrievalResultsRaw: unknown[]; - retrievalResultsNormalized: unknown[]; - requirementsExtracted: unknown[]; + resolvedExecutionState: AssistantExecutionStateRecord[]; + routes: AssistantDebugRouteRecord[]; + retrievalCalls: AssistantRetrievalCallRecord[]; + retrievalResultsRaw: AssistantRetrievalRawResultRecord[]; + retrievalResultsNormalized: UnifiedRetrievalResult[]; + requirementsExtracted: AssistantRequirement[]; coverageReport: RequirementCoverageReport; groundingCheck: AnswerGroundingCheck; - replyType: string; + replyType: AssistantReplyType; droppedIntentSegments: string[]; questionTypeClass: string; - companyAnchors: unknown; + companyAnchors: CompanyAnchorSet | null; runtimeAnalysisContext: { active: boolean; as_of_date: string | null; @@ -32,26 +61,26 @@ export interface DeepAnalysisMessageLogDetailsInput { company_grounding_applied?: boolean; scope_resolution_reason?: string[]; }; - temporalGuard: Record; - polarityAudit: Record; - claimAnchorAudit: Record; - targetedEvidenceAudit: unknown; - evidenceAdmissibilityGateAudit: unknown; - rbpLiveRouteAudit: unknown | null; - faLiveRouteAudit: unknown | null; - groundedAnswerEligibilityGuard: Record; - followupStateUsage: unknown | null; + temporalGuard: TemporalGuardAudit; + polarityAudit: DomainPolarityGuardAudit; + claimAnchorAudit: ClaimBoundAnchorAudit; + targetedEvidenceAudit: TargetedEvidenceAcquisitionAudit; + evidenceAdmissibilityGateAudit: EvidenceAdmissibilityAudit; + rbpLiveRouteAudit: RbpLiveRouteAuditDebug | null; + faLiveRouteAudit: FaLiveRouteAuditDebug | null; + groundedAnswerEligibilityGuard: GroundedAnswerEligibilityAudit; + followupStateUsage: AssistantFollowupUsage | null; compositionDebug: { problem_centric_answer_applied?: boolean; problem_units_used_count?: number; - problem_answer_mode?: string; + problem_answer_mode?: AssistantProblemAnswerMode; problem_unit_ids_used?: string[]; - fallback_type?: string; + fallback_type?: AssistantFallbackType; }; - outcomeClassV1: unknown; - assistantOrchestrationContractsV1: unknown; - answerStructureV11: unknown; - investigationStateSnapshot: unknown; + outcomeClassV1: AssistantOutcomeClassV1; + assistantOrchestrationContractsV1: AssistantContractsBundleV1["assistantOrchestrationContractsV1"]; + answerStructureV11: AnswerStructureV11 | null; + investigationStateSnapshot: InvestigationStateWithProblemUnits | null; assistantReply: string; traceId: string; } @@ -77,7 +106,9 @@ function resolveCoverageStatus(coverageReport: RequirementCoverageReport): "full : "partial_or_limited"; } -export function buildDeepAnalysisProcessedLogDetails(input: DeepAnalysisMessageLogDetailsInput): Record { +export type DeepAnalysisLogDetails = Record; + +export function buildDeepAnalysisProcessedLogDetails(input: DeepAnalysisMessageLogDetailsInput): DeepAnalysisLogDetails { const analysisContext = toAnalysisContext(input.runtimeAnalysisContext); return { session_id: input.sessionId, diff --git a/llm_normalizer/backend/src/services/assistantOrchestrationContracts.ts b/llm_normalizer/backend/src/services/assistantOrchestrationContracts.ts index 0b0302f..708fb47 100644 --- a/llm_normalizer/backend/src/services/assistantOrchestrationContracts.ts +++ b/llm_normalizer/backend/src/services/assistantOrchestrationContracts.ts @@ -6,6 +6,7 @@ import type { UnifiedRetrievalResult } from "../types/assistant"; import type { NormalizedPayload, RouteHintSummary } from "../types/normalizer"; +import type { AssistantRetrievalCallRecord } from "./assistantDeepTurnRetrievalRuntimeAdapter"; export type AssistantOutcomeClassV1 = | "FULLY_ANSWERED" @@ -241,7 +242,7 @@ export function buildAssistantExecutionPlanContractV1(input: { } export function buildAssistantEvidenceBundleContractV1(input: { - retrievalCalls: Array>; + retrievalCalls: AssistantRetrievalCallRecord[]; retrievalResults: UnifiedRetrievalResult[]; }): AssistantEvidenceBundleContractV1 { const retrievalResults = Array.isArray(input.retrievalResults) ? input.retrievalResults : []; diff --git a/llm_normalizer/backend/src/services/assistantQueryPlanning.ts b/llm_normalizer/backend/src/services/assistantQueryPlanning.ts index 851948e..a69e9bd 100644 --- a/llm_normalizer/backend/src/services/assistantQueryPlanning.ts +++ b/llm_normalizer/backend/src/services/assistantQueryPlanning.ts @@ -1,3 +1,4 @@ +import type { AssistantDebugRouteRecord } from "../types/assistant"; import type { RouteHintSummary } from "../types/normalizer"; interface FragmentLike { @@ -106,7 +107,7 @@ export function buildExecutionPlanFromRoute(input: { export function buildDebugRoutesFromRoute(input: { routeSummary: RouteHintSummary | null; resolveLegacyRouteReason: (route: string) => string; -}): Array> { +}): AssistantDebugRouteRecord[] { if (!input.routeSummary) { return []; } diff --git a/llm_normalizer/backend/src/services/assistantRuntimeGuards.ts b/llm_normalizer/backend/src/services/assistantRuntimeGuards.ts index d7fbf2d..cff2716 100644 --- a/llm_normalizer/backend/src/services/assistantRuntimeGuards.ts +++ b/llm_normalizer/backend/src/services/assistantRuntimeGuards.ts @@ -4,6 +4,7 @@ import type { CompanyAnchorSet } from "./companyAnchorResolver"; import type { EvidenceItem } from "../types/stage1Contracts"; import type { ProblemUnit } from "../types/stage2ProblemUnits"; import type { ClaimBoundAnchorAudit } from "./assistantClaimBoundEvidence"; +import iconv from "iconv-lite"; type P0DomainHint = | "settlements_60_62" @@ -895,12 +896,70 @@ export interface DomainPolarityGuardAudit { reason_codes: string[]; } +function mojibakeScoreForRuntimeGuards(value: string): number { + const source = String(value ?? ""); + const cyrillic = (source.match(/[А-Яа-яЁё]/g) ?? []).length; + const latin = (source.match(/[A-Za-z]/g) ?? []).length; + const hardMarkers = (source.match(/[ѓ“‚„…†‡€‰‹‰ЉЊ‹Џ‘’“”•–—™љ›њћџ]/g) ?? []).length; + const pairMarkers = (source.match(/(?:Р.|С.|Гђ.|Г‘.)/g) ?? []).length; + const doubleEncodedMarkers = (source.match(/(?:Р“.|Р’.|Гѓ.|Г‚.)/gu) ?? []).length; + return cyrillic + latin - hardMarkers * 3 - pairMarkers * 2 - doubleEncodedMarkers * 2; +} + +function looksLikeMojibakeForRuntimeGuards(value: string): boolean { + const source = String(value ?? ""); + if (!source.trim()) { + return false; + } + if (/[ѓ“‚„…†‡€‰‹‰ЉЊ‹Џ‘’“”•–—™љ›њћџ]/.test(source)) { + return true; + } + if ((source.match(/(?:Р.|С.|Гђ.|Г‘.)/g) ?? []).length >= 2) { + return true; + } + return (source.match(/(?:Р“.|Р’.|Гѓ.|Г‚.)/gu) ?? []).length >= 2; +} + +function repairRuntimeGuardsMojibake(value: string): string { + const source = String(value ?? ""); + if (!looksLikeMojibakeForRuntimeGuards(source)) { + return source; + } + let candidate = source; + for (let pass = 0; pass < 3; pass += 1) { + let improved = false; + try { + const fromWin1251 = iconv.encode(candidate, "win1251").toString("utf8"); + if (mojibakeScoreForRuntimeGuards(fromWin1251) > mojibakeScoreForRuntimeGuards(candidate)) { + candidate = fromWin1251; + improved = true; + } + } catch (_error) { + // noop + } + try { + const fromLatin1 = Buffer.from(candidate, "latin1").toString("utf8"); + if (mojibakeScoreForRuntimeGuards(fromLatin1) > mojibakeScoreForRuntimeGuards(candidate)) { + candidate = fromLatin1; + improved = true; + } + } catch (_error) { + // noop + } + if (!improved) { + break; + } + } + return candidate; +} + export function resolveDomainPolarityGuard(input: { userMessage: string; companyAnchors?: CompanyAnchorSet | null; focusDomainHint?: string | null; }): DomainPolarityGuardAudit { - const lower = String(input.userMessage ?? "").toLowerCase(); + const repairedMessage = repairRuntimeGuardsMojibake(String(input.userMessage ?? "")); + const lower = repairedMessage.toLowerCase(); const accountExtraction = extractAccountsFromTextDetailed(lower); const accounts = uniqueStrings([...(input.companyAnchors?.accounts ?? []), ...accountExtraction.resolved_account_anchors]); const prefixes = new Set(accounts.map((item) => accountPrefix(item)).filter((item): item is string => Boolean(item))); @@ -1683,7 +1742,8 @@ export function applyEligibilityToGroundingCheck = { admissible_evidence_count_zero: "Недостаточно подтвержденных данных для уверенного ответа.", critical_domain_or_account_contradiction: "Есть противоречие по выбранному домену или контуру счета.", - temporal_guard_failed_out_of_snapshot_window: "Запрошенный период выходит за доступный срез данных.", + temporal_guard_failed_out_of_snapshot_window: + "Запрошенный период выходит за доступный срез данных. Temporal anchor outside snapshot window.", temporal_guard_ambiguous_limited: "Период в вопросе определен недостаточно точно.", business_scope_generic_unresolved: "Не удалось надежно привязать вопрос к конкретному бизнес-контексту.", polarity_guard_limited_unresolved_polarity: "Не удалось однозначно определить сторону расчета (нам должны или мы должны).", diff --git a/llm_normalizer/backend/src/services/assistantService.ts b/llm_normalizer/backend/src/services/assistantService.ts index b1abc96..0c64288 100644 --- a/llm_normalizer/backend/src/services/assistantService.ts +++ b/llm_normalizer/backend/src/services/assistantService.ts @@ -1040,7 +1040,12 @@ function hasCrossScopeConflictWithState(userMessage, state) { const inferredDomain = inferP0DomainFromMessage(userMessage); const stateDomain = compactWhitespace(state.followup_context?.active_domain ?? state.focus.domain ?? ""); if (inferredDomain && stateDomain && inferredDomain !== stateDomain) { - return true; + const followupDomainRefinement = hasFollowupMarker(userMessage) || + hasReferentialPointer(userMessage) || + hasPeriodLiteral(userMessage); + if (!followupDomainRefinement) { + return true; + } } const explicitAccounts = extractAccountTokens(userMessage); const fallbackAccounts = explicitAccounts.length > 0 ? explicitAccounts : extractFollowupAccountAnchorsLoose(userMessage); @@ -1070,9 +1075,11 @@ function inferP0DomainFromMessage(text) { return null; } function hasStrongFollowupAnchors(userMessage, state) { + const normalizedMessage = compactWhitespace(repairAddressMojibake(String(userMessage ?? "")).toLowerCase()); + const periodRefinementCue = /(?:^(?:\u0430\s+)?\u0435\u0441\u043b\u0438|\u0442\u043e\u043b\u044c\u043a\u043e\s+\u0437\u0430|\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c|\u043f\u043e\s+\u043f\u0435\u0440\u0438\u043e\u0434\u0443|\u0437\u0430\s+\u0438\u044e\u043d\u044c|\u0437\u0430\s+\u0438\u044e\u043b\u044c)/iu.test(normalizedMessage); const explicitPeriod = extractNormalizedPeriodLiteral(userMessage); if (explicitPeriod && state.focus.period && explicitPeriod !== state.focus.period) { - const periodLooksLikeFollowupRefinement = hasFollowupMarker(userMessage) || hasReferentialPointer(userMessage); + const periodLooksLikeFollowupRefinement = hasFollowupMarker(userMessage) || hasReferentialPointer(userMessage) || periodRefinementCue; if (!periodLooksLikeFollowupRefinement) { return true; } @@ -2969,26 +2976,33 @@ function resolveAddressToolGateDecision(addressInputMessage, followupContext, ll reason: dataScopeMetaQuery ? "assistant_data_scope_query_detected" : "assistant_capability_query_detected" }; } + const directDeepAnalysisSignal = hasDirectDeepAnalysisSignal(rawMessageForGate) || + hasDirectDeepAnalysisSignal(repairedInputMessage); + const deepAnalysisPreferenceSignal = directDeepAnalysisSignal || + hasDeepAnalysisPreferenceSignal(rawMessageForGate) || + hasDeepAnalysisPreferenceSignal(repairedInputMessage); const modeDetection = (0, addressQueryClassifier_1.detectAddressQuestionMode)(repairedInputMessage || addressInputMessage); const hasClassifierSignal = modeDetection.mode === "address_query"; const llmContractMode = toNonEmptyString(llmPreDecomposeMeta?.predecomposeContract?.mode); const llmContractModeConfidence = toNonEmptyString(llmPreDecomposeMeta?.predecomposeContract?.mode_confidence); const llmContractIntent = toNonEmptyString(llmPreDecomposeMeta?.predecomposeContract?.intent); - const llmContractIntentConfidence = toNonEmptyString(llmPreDecomposeMeta?.predecomposeContract?.intent_confidence); + const llmCanonicalEntitySignal = /(?:\u0437\u0430\u043a\u0430\u0437\u0447\u0438\u043a|\u043f\u043e\u0441\u0442\u0430\u0432\u0449\u0438\u043a|\u043a\u043e\u043d\u0442\u0440\u0430\u0433\u0435\u043d\u0442|\u043a\u043e\u043c\u043f\u0430\u043d|customer|supplier|counterparty|company|vendor|client|\b[a-z]{2,}\b)/iu.test(compactWhitespace(repairedInputMessage.toLowerCase())); + const llmCanonicalAppliedSignal = Boolean(llmPreDecomposeMeta?.applied) && llmContractMode !== "deep_analysis"; const hasLlmCanonicalSignal = Boolean(llmPreDecomposeMeta?.llmCanonicalCandidateDetected) && - llmContractMode === "address_query" && - llmContractModeConfidence !== "low" && - llmContractIntent !== null && - llmContractIntent !== "unknown" && - llmContractIntentConfidence !== "low"; + ((llmContractMode === "address_query" && llmContractModeConfidence !== "low") || + (llmCanonicalAppliedSignal && + (hasStrongDataIntentSignal(repairedInputMessage) || llmCanonicalEntitySignal || llmContractMode === "unsupported"))); const hasLlmCanonicalDataSignal = Boolean(llmPreDecomposeMeta?.llmCanonicalCandidateDetected) && Boolean(llmPreDecomposeMeta?.applied) && - llmContractMode === "address_query" && + (llmContractMode === "address_query" || llmContractMode === "unsupported" || llmContractMode === null) && hasStrongDataIntentSignal(repairedInputMessage); + const sameDateAccountFollowupSignal = hasSameDateAccountFollowupSignalForPredecompose(rawMessageForGate) || + hasSameDateAccountFollowupSignalForPredecompose(repairedInputMessage); const hasLexicalAddressSignal = isAddressLlmPreDecomposeCandidate(addressInputMessage) || isAddressLlmPreDecomposeCandidate(repairedInputMessage) || hasAccountingSignal(addressInputMessage) || - hasAccountingSignal(repairedInputMessage); + hasAccountingSignal(repairedInputMessage) || + sameDateAccountFollowupSignal; const hasUnsupportedLowConfidencePredecomposeSignal = llmContractMode === "unsupported" && (llmContractModeConfidence === "low" || llmContractModeConfidence === "medium") && llmContractIntent === "unknown"; @@ -3036,6 +3050,89 @@ function resolveAddressToolGateDecision(addressInputMessage, followupContext, ll reason: "no_address_signal_after_l0" }; } +function hasLooseAllTimeAddressLookupSignal(text) { + const repaired = repairAddressMojibake(String(text ?? "")); + const normalized = compactWhitespace(repaired.toLowerCase()); + if (!normalized) { + return false; + } + if (shouldHandleAsAssistantCapabilityMetaQuery(normalized) || hasAssistantDataScopeMetaQuestionSignal(normalized)) { + return false; + } + const hasAllTimeSignal = /(?:\u0437\u0430\s+\u0432\u0435\u0441\u044c\s+\u043f\u0435\u0440\u0438\u043e\u0434|\u0437\u0430\s+\u0432\u0441\u0435\s+\u0432\u0440\u0435\u043c\u044f|\u0437\u0430\s+\u0432\u0441\u044e\s+\u0438\u0441\u0442\u043e\u0440\u0438(?:\u044e|\u0438)|for\s+all\s+time|all\s+time|entire\s+period|full\s+period)/iu.test(normalized); + if (!hasAllTimeSignal) { + return false; + } + return /(?:\u0447\u0442\u043e\s+\u0435\u0441\u0442\u044c|\u0447[\u0435\u0451]\s+\u0435\u0441\u0442\u044c|\u043f\u043e\u043a\u0430\u0436\u0438|\u0432\u044b\u0432\u0435\u0434\u0438|\u0434\u0430\u0439|show|list|find)/iu.test(normalized); +} +function hasDeepSessionContinuationSignal(input) { + const sessionItems = Array.isArray(input?.sessionItems) ? input.sessionItems : []; + if (sessionItems.length === 0) { + return false; + } + const previousDebug = findLastAssistantLivingChatDebug(sessionItems); + if (!previousDebug || typeof previousDebug !== "object") { + return false; + } + const investigationState = previousDebug.investigation_state_snapshot; + if (!investigationState || typeof investigationState !== "object") { + return false; + } + const candidateTexts = [ + input?.rawUserMessage, + input?.repairedRawUserMessage, + input?.effectiveAddressUserMessage, + input?.repairedEffectiveAddressUserMessage + ] + .map((value) => compactWhitespace(repairAddressMojibake(String(value ?? "")).toLowerCase())) + .filter((value) => value.length > 0); + if (candidateTexts.length === 0) { + return false; + } + return candidateTexts.some((text) => { + const hasContinuationCue = /^(?:\u0438|\u0430|\u0442\u0430\u043a\u0436\u0435|\u0435\u0449[\u0435\u0451]|\u0434\u043e\u0431\u0430\u0432\u044c|\u0434\u043e\u043f\u043e\u043b\u043d\u0438|\u0443\u0442\u043e\u0447\u043d\u0438|\u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0438|\u0442\u0435\u043f\u0435\u0440\u044c|then|also|and)\b/iu.test(text) || + /(?:\u043f\u043e\s+\u0442\u043e\u043c\u0443\s+\u0436\u0435|\u043f\u043e\s+\u044d\u0442\u043e\u043c\u0443|\u0432\s+\u044d\u0442\u043e\u043c\s+\u0436\u0435|\u0438\s+\u043f\u043e\s+\u043f\u0435\u0440\u0438\u043e\u0434\u0443|\u0434\u043e\u0431\u0430\u0432\u044c\s+\u0443\u0442\u043e\u0447\u043d\u0435\u043d\u0438\u0435|\u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0438\u043c|\u0430\s+\u0435\u0441\u043b\u0438|\u0435\u0441\u043b\u0438\s+\u0442\u043e\u043b\u044c\u043a\u043e|\u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e)/iu.test(text); + const hasAccountOrPeriodCue = /(?:\u0441\u0447[\u0435\u0451]\u0442|account|\b\d{2}(?:[.,]\d{1,2})?\b|\b20\d{2}(?:[-/.]\d{1,2})?\b|\u043f\u0435\u0440\u0438\u043e\u0434|\u043c\u0435\u0441\u044f\u0446)/iu.test(text); + const hasDeepRebindCue = /(?:\u0430\u043c\u043e\u0440\u0442\u0438\u0437|fixed\s*asset|\u043e\u0441\b|\u043d\u0434\u0441|vat|\u0440\u0430\u0437\u0440\u044b\u0432|\u0446\u0435\u043f\u043e\u0447\u043a|\u0430\u043d\u043e\u043c\u0430\u043b|lifecycle|\u043f\u0440\u043e\u0442\u0438\u0432\u043e\u0440\u0435\u0447)/iu.test(text); + if (hasContinuationCue && (hasAccountOrPeriodCue || hasDeepRebindCue)) { + return true; + } + return hasDeepRebindCue && hasAccountOrPeriodCue; + }); +} +function hasDeepAnalysisPreferenceSignal(text) { + const repaired = repairAddressMojibake(String(text ?? "")); + const lower = compactWhitespace(repaired.toLowerCase()); + if (!lower) { + return false; + } + const riskOrAnomalySignal = /(?:\u0440\u0438\u0441\u043a|risk|\u0430\u043d\u043e\u043c\u0430\u043b|anomal|\u043f\u0440\u043e\u0442\u0438\u0432\u043e\u0440\u0435\u0447|\u043a\u043e\u043d\u0444\u043b\u0438\u043a\u0442|conflict|deviation|\u043e\u0442\u043a\u043b\u043e\u043d\u0435\u043d|\u043d\u0435\u0441\u044b\u043a\u043e\u0432\u043a|\u043d\u0435\u0441\u0445\u043e\u0434|\u043e\u0448\u0438\u0431|error|issue|\u043f\u0440\u043e\u0431\u043b\u0435\u043c)/iu.test(lower); + const chainSignal = /(?:\u0446\u0435\u043f\u043e\u0447\u043a|chain|trace\s*chain|lifecycle|\u0436\u0438\u0437\u043d\u0435\u043d\u043d[\u0430-\u044f]+\s+\u0446\u0438\u043a\u043b|state\s+transition|\u0440\u0430\u0437\u0440\u044b\u0432[\u0430-\u044f]*)/iu.test(lower); + const diagnosticsSignal = /(?:\u0440\u0430\u0437\u043b\u043e\u0436\u0438|\u0434\u0435\u043a\u043e\u043c\u043f\u043e\u0437|\u0440\u0430\u0437\u0431\u0435\u0440\u0438|\u043f\u043e\u0447\u0435\u043c\u0443|why|\u043a\u043e\u0440\u043d\u0435\u0432[\u0430-\u044f]+\s+\u043f\u0440\u0438\u0447\u0438\u043d|root\s*cause|\u043c\u0435\u0445\u0430\u043d\u0438\u0437\u043c[\u0430-\u044f]*|\u0433\u0434\u0435\s+\u0440\u0430\u0437\u0440\u044b\u0432|\u0447\u0442\u043e\s+\u043c\u0435\u0448\u0430[\u0430-\u044f]+\s+\u0437\u0430\u043a\u0440\u044b\u0442)/iu.test(lower); + const closureSignal = /(?:\u0437\u0430\u043a\u0440\u044b\u0442\u0438[\u0435\u044f]\s+\u043f\u0435\u0440\u0438\u043e\u0434|period\s*close|\u043d\u0435\s+\u0437\u0430\u043a\u0440\u044b\u043b[\u0430-\u044f]*|\u0445\u0432\u043e\u0441\u0442[\u0430-\u044f]*)/iu.test(lower); + const closureIntentSignal = /(?:\u0437\u0430\u043a\u0440\u044b\u0442[\u0430-\u044f]*|period\s*close|close\s+period)/iu.test(lower); + const closureDiagnosticPhraseSignal = /(?:\u0447\u0442\u043e(?:\s+\S+){0,8}\s+\u043c\u0435\u0448\u0430[\u0430-\u044f]+\s+\u0437\u0430\u043a\u0440\u044b\u0442)/iu.test(lower); + const signalVsNoiseDiagnostic = /(?:\u043d\u0435\s+\u043f\u0440\u043e\u0441\u0442\u043e\s+(?:\u043d\u0430\s+)?\u0448\u0443\u043c|\u043f\u043e\u0445\u043e\u0436[\u0438\u0435]\s+(?:\u0438\u043c\u0435\u043d\u043d\u043e\s+)?\u043d\u0430\s+\u043f\u0440\u043e\u0431\u043b\u0435\u043c)/iu.test(lower); + const lifecycleMismatchSignal = /(?:\u043d\u0435\s+\u0442\u0435\u043c\s+\u0442\u0438\u043f(?:\u043e\u043c)?\s+\u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442|\u043e\u0436\u0438\u0434\u0430\u0435\u043c[\u0430-\u044f]+\s+\u043f\u0435\u0440\u0435\u0445\u043e\u0434[\u0430-\u044f]*\s+\u043d\u0435\s+\u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434|\u043f\u0435\u0440\u0435\u0445\u043e\u0434[\u0430-\u044f]*\s+\u043d\u0435\s+\u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434|wrong\s+closing\s+document|expected\s+transition)/iu.test(lower); + const lifecycleTransitionGapSignal = /(?:\u043e\u0436\u0438\u0434\u0430\u0435\u043c[\u0430-\u044f]+\s+\u043f\u0435\u0440\u0435\u0445\u043e\u0434[\u0430-\u044f]*\s+\u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432|\u043f\u0435\u0440\u0435\u0445\u043e\u0434[\u0430-\u044f]*\s+\u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432|\u0441\u0442\u0430\u0434\u0438[\u0438\u044f\u0435]\s+.*\u043f\u0440\u043e\u0439\u0434\u0435\u043d.*\u043f\u0435\u0440\u0435\u0445\u043e\u0434)/iu.test(lower); + const expectedActualMismatchSignal = /(?:\u0444\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a[\u0430-\u044f]+\s+\u0441\u043e\u0441\u0442\u043e\u044f\u043d[\u0438\u0435\u044f]+\s+.*\u0440\u0430\u0441\u0445\u043e\u0434[\u0430-\u044f]*\s+\u0441\s+\u043e\u0436\u0438\u0434\u0430\u0435\u043c|\u043e\u0436\u0438\u0434\u0430\u0435\u043c[\u0430-\u044f]+\s+\u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d[\u0430-\u044f]*\s+\u0441\u043f\u0438\u0441\u0430\u043d)/iu.test(lower); + return riskOrAnomalySignal || + lifecycleMismatchSignal || + (chainSignal && lifecycleTransitionGapSignal) || + expectedActualMismatchSignal || + (chainSignal && diagnosticsSignal) || + (riskOrAnomalySignal && (chainSignal || closureSignal || diagnosticsSignal || closureIntentSignal)) || + (diagnosticsSignal && closureIntentSignal) || + closureDiagnosticPhraseSignal || + signalVsNoiseDiagnostic; +} +function hasDirectDeepAnalysisSignal(text) { + const normalized = compactWhitespace(repairAddressMojibake(String(text ?? "")).toLowerCase()); + if (!normalized) { + return false; + } + return /(?:\u0440\u0430\u0437\u043b\u043e\u0436|\u0446\u0435\u043f\u043e\u0447|lifecycle|\u0440\u0430\u0437\u0440\u044b\u0432|\u043f\u0440\u043e\u0442\u0438\u0432\u043e\u0440\u0435\u0447|\u0430\u043d\u043e\u043c\u0430\u043b|\u043f\u043e\u0447\u0435\u043c\u0443|\u043c\u0435\u0445\u0430\u043d\u0438\u0437\u043c|\u0437\u0430\u043a\u0440\u044b\u0442[\u0430-\u044f]*|state\s+transition|root\s*cause|trace\s*chain)/iu.test(normalized); +} export function resolveAssistantOrchestrationDecision(input) { const rawUserMessage = String(input?.rawUserMessage ?? input?.userMessage ?? ""); const effectiveAddressUserMessage = String(input?.effectiveAddressUserMessage ?? rawUserMessage); @@ -3044,6 +3141,7 @@ export function resolveAssistantOrchestrationDecision(input) { const followupContext = input?.followupContext ?? null; const llmPreDecomposeMeta = input?.llmPreDecomposeMeta ?? null; const useMock = Boolean(input?.useMock); + const sessionItems = Array.isArray(input?.sessionItems) ? input.sessionItems : null; const dataScopeMetaQuery = hasAssistantDataScopeMetaQuestionSignal(rawUserMessage) || hasAssistantDataScopeMetaQuestionSignal(repairedRawUserMessage) || hasAssistantDataScopeMetaQuestionSignal(effectiveAddressUserMessage) || @@ -3131,11 +3229,52 @@ export function resolveAssistantOrchestrationDecision(input) { }; } const baseToolGate = resolveAddressToolGateDecision(effectiveAddressUserMessage, followupContext, llmPreDecomposeMeta, rawUserMessage); + const llmContractMode = toNonEmptyString(llmPreDecomposeMeta?.predecomposeContract?.mode); + const preserveAddressLaneSignal = Boolean((llmPreDecomposeMeta?.llmCanonicalCandidateDetected && + llmPreDecomposeMeta?.applied && + (llmContractMode === "address_query" || llmContractMode === "unsupported")) || + hasSameDateAccountFollowupSignalForPredecompose(rawUserMessage) || + hasSameDateAccountFollowupSignalForPredecompose(effectiveAddressUserMessage) || + hasSameDateAccountFollowupSignalForPredecompose(repairedRawUserMessage) || + hasSameDateAccountFollowupSignalForPredecompose(repairedEffectiveAddressUserMessage) || + hasLooseAllTimeAddressLookupSignal(rawUserMessage) || + hasLooseAllTimeAddressLookupSignal(effectiveAddressUserMessage) || + hasLooseAllTimeAddressLookupSignal(repairedRawUserMessage) || + hasLooseAllTimeAddressLookupSignal(repairedEffectiveAddressUserMessage) || + hasAddressFollowupContextSignal(rawUserMessage) || + hasAddressFollowupContextSignal(effectiveAddressUserMessage) || + hasAddressFollowupContextSignal(repairedRawUserMessage) || + hasAddressFollowupContextSignal(repairedEffectiveAddressUserMessage)); const unsupportedAddressIntentFallbackToDeep = Boolean(!followupContext && baseToolGate?.runAddressLane && modeDetection.mode !== "address_query" && intentResolution.intent === "unknown" && - strongDataSignal); + strongDataSignal && + !preserveAddressLaneSignal); + const deepAnalysisPreferenceDetected = Boolean(hasDeepAnalysisPreferenceSignal(rawUserMessage) || + hasDeepAnalysisPreferenceSignal(repairedRawUserMessage) || + hasDeepAnalysisPreferenceSignal(effectiveAddressUserMessage) || + hasDeepAnalysisPreferenceSignal(repairedEffectiveAddressUserMessage) || + hasDirectDeepAnalysisSignal(rawUserMessage) || + hasDirectDeepAnalysisSignal(repairedRawUserMessage) || + hasDirectDeepAnalysisSignal(effectiveAddressUserMessage) || + hasDirectDeepAnalysisSignal(repairedEffectiveAddressUserMessage)); + 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}`))); + const deepAnalysisSignalFallbackToDeep = Boolean(baseToolGate?.runAddressLane && + deepAnalysisPreferenceDetected && + !vatExplainFollowupSignal && + (!followupContext || !dataRetrievalSignal)); + const deepSessionContinuationFallbackToDeep = Boolean(!followupContext && + baseToolGate?.runAddressLane && + hasDeepSessionContinuationSignal({ + rawUserMessage, + repairedRawUserMessage, + effectiveAddressUserMessage, + repairedEffectiveAddressUserMessage, + sessionItems + })); let runAddressLane = Boolean(baseToolGate?.runAddressLane); let toolGateDecision = String(baseToolGate?.decision ?? "skip_address_lane"); let toolGateReason = String(baseToolGate?.reason ?? "no_address_signal_after_l0"); @@ -3144,6 +3283,16 @@ export function resolveAssistantOrchestrationDecision(input) { toolGateDecision = "skip_address_lane"; toolGateReason = "address_signal_unsupported_intent_fallback_to_deep"; } + if (deepAnalysisSignalFallbackToDeep && !unsupportedAddressIntentFallbackToDeep) { + runAddressLane = false; + toolGateDecision = "skip_address_lane"; + toolGateReason = "deep_analysis_signal_fallback_to_deep"; + } + if (deepSessionContinuationFallbackToDeep) { + runAddressLane = false; + toolGateDecision = "skip_address_lane"; + toolGateReason = "deep_session_continuation_fallback_to_deep"; + } let livingDecision = resolveLivingAssistantModeDecision({ userMessage: rawUserMessage, addressLaneTriggered: runAddressLane, @@ -3157,6 +3306,18 @@ export function resolveAssistantOrchestrationDecision(input) { reason: "unsupported_address_intent_fallback_to_deep" }; } + if (deepAnalysisSignalFallbackToDeep && !unsupportedAddressIntentFallbackToDeep) { + livingDecision = { + mode: "deep_analysis", + reason: "deep_analysis_signal_fallback_to_deep" + }; + } + if (deepSessionContinuationFallbackToDeep) { + livingDecision = { + mode: "deep_analysis", + reason: "deep_session_continuation_fallback_to_deep" + }; + } return { runAddressLane, toolGateDecision, @@ -3174,6 +3335,8 @@ export function resolveAssistantOrchestrationDecision(input) { data_retrieval_signal_detected: dataRetrievalSignal, followup_context_detected: Boolean(followupContext), unsupported_address_intent_fallback_to_deep: unsupportedAddressIntentFallbackToDeep, + deep_analysis_signal_fallback_to_deep: deepAnalysisSignalFallbackToDeep, + deep_session_continuation_fallback_to_deep: deepSessionContinuationFallbackToDeep, final_decision: { run_address_lane: runAddressLane, tool_gate_decision: toolGateDecision, diff --git a/llm_normalizer/backend/src/services/assistantTurnRuntimeDepsAdapter.ts b/llm_normalizer/backend/src/services/assistantTurnRuntimeDepsAdapter.ts index 2ded1f9..72715a0 100644 --- a/llm_normalizer/backend/src/services/assistantTurnRuntimeDepsAdapter.ts +++ b/llm_normalizer/backend/src/services/assistantTurnRuntimeDepsAdapter.ts @@ -85,12 +85,12 @@ export function buildAssistantTurnRuntimeDeps( ): AssistantTurnRuntimeBuilderDeps { return { ...input.helpers, - ensureSession: input.sessions.ensureSession, - appendItem: input.sessions.appendItem, - getSession: input.sessions.getSession, - persistSession: input.sessionLogger.persistSession, - setInvestigationState: input.sessions.setInvestigationState, - normalize: input.normalizerService.normalize, + ensureSession: (sessionId) => input.sessions.ensureSession(sessionId), + appendItem: (sessionId, item) => input.sessions.appendItem(sessionId, item), + getSession: (sessionId) => input.sessions.getSession(sessionId), + persistSession: (session) => input.sessionLogger.persistSession(session), + setInvestigationState: (sessionId, state) => input.sessions.setInvestigationState(sessionId, state), + normalize: (payload) => input.normalizerService.normalize(payload), executeRouteRuntime: (route, fragmentText, options) => input.dataLayer.executeRouteRuntime(route, fragmentText, options), tryAddressQueryHandle: (messageUsed, options) => input.addressQueryService.tryHandle(messageUsed, options), diff --git a/llm_normalizer/backend/src/types/assistant.ts b/llm_normalizer/backend/src/types/assistant.ts index 8c4665d..ce00ca9 100644 --- a/llm_normalizer/backend/src/types/assistant.ts +++ b/llm_normalizer/backend/src/types/assistant.ts @@ -1,4 +1,13 @@ -import type { NormalizeRequestPayload, NormalizeResponsePayload, RouteHintSummary } from "./normalizer"; +import type { + NormalizeRequestPayload, + NormalizeResponsePayload, + NoRouteReason, + RouteHintSummary, + RouteStatus, + ExecutionReadiness, + ConfidenceLevel, + IntentClass +} from "./normalizer"; import type { AnswerStructureV11, EvidenceItem } from "./stage1Contracts"; import type { CandidateEvidenceItem, @@ -27,6 +36,43 @@ export type AssistantProblemAnswerMode = | "stage2_problem_centric_v1" | "stage3_lifecycle_aware_v1"; +export interface AssistantExecutionStateRecord { + fragment_id: string | null; + execution_readiness: ExecutionReadiness | null; + route_status: RouteStatus | null; + no_route_reason: NoRouteReason | null; +} + +export type AssistantDebugRouteRecord = + | { + fragment_id: string; + route: string; + reason: string; + confidence: ConfidenceLevel; + intent_class: IntentClass; + } + | { + fragment_id: string; + route: string; + reason: string; + route_status: RouteStatus | null; + no_route_reason: NoRouteReason | null; + clarification_reason: string | null; + execution_readiness: ExecutionReadiness | null; + }; + +export interface AssistantAddressRuntimeMetaForDeep { + attempted?: boolean; + applied?: boolean; + reason?: string | null; + provider?: string | null; + fallbackRuleHit?: string | null; + toolGateDecision?: string | null; + toolGateReason?: string | null; + predecomposeContract?: Record | null; + orchestrationContract?: Record | null; +} + export interface AssistantRequirement { requirement_id: string; source_fragment_id: string | null; @@ -302,7 +348,7 @@ export interface AssistantDebugPayload { fragments: unknown[]; requirements_extracted: AssistantRequirement[]; coverage_report: RequirementCoverageReport; - routes: Array>; + routes: AssistantDebugRouteRecord[]; retrieval_status: Array<{ fragment_id: string; requirement_ids: string[]; diff --git a/llm_normalizer/backend/src/utils/log.ts b/llm_normalizer/backend/src/utils/log.ts index dfddbde..67850e7 100644 --- a/llm_normalizer/backend/src/utils/log.ts +++ b/llm_normalizer/backend/src/utils/log.ts @@ -32,6 +32,9 @@ function redactObject(value: unknown): unknown { } export function logJson(entry: JsonLogEntry): void { + if (process.env.NODE_ENV === "test" && process.env.FEATURE_JSON_STDOUT_LOGS_IN_TESTS !== "1") { + return; + } const safe = { ...entry, details: redactObject(entry.details) diff --git a/llm_normalizer/backend/tests/assistantLivingRouter.test.ts b/llm_normalizer/backend/tests/assistantLivingRouter.test.ts index 97b2ff9..adc2f82 100644 --- a/llm_normalizer/backend/tests/assistantLivingRouter.test.ts +++ b/llm_normalizer/backend/tests/assistantLivingRouter.test.ts @@ -261,4 +261,40 @@ describe("assistant orchestration contract", () => { decision.toolGateReason ); }); + + it("routes risk/anomaly analytics wording to deep pipeline", () => { + const decision = resolveAssistantOrchestrationDecision({ + rawUserMessage: "Проверь НДС по счету 19 за 2020-06 и рискованные записи по документам.", + effectiveAddressUserMessage: "Проверь НДС по счету 19 за 2020-06 и рискованные записи по документам.", + followupContext: null, + llmPreDecomposeMeta: null, + useMock: false + }); + + expect(decision.runAddressLane).toBe(false); + expect(decision.toolGateDecision).toBe("skip_address_lane"); + expect(decision.toolGateReason).toBe("deep_analysis_signal_fallback_to_deep"); + expect(decision.livingMode).toBe("deep_analysis"); + expect(decision.livingReason).toBe("deep_analysis_signal_fallback_to_deep"); + expect(decision.orchestrationContract?.deep_analysis_signal_fallback_to_deep).toBe(true); + }); + + it("routes settlement closure verification wording to deep pipeline", () => { + const decision = resolveAssistantOrchestrationDecision({ + rawUserMessage: + "По оплате поставщику на счете 60 в июле 2020 остался хвост. Проверь закрытие по договору и объекту расчетов.", + effectiveAddressUserMessage: + "По оплате поставщику на счете 60 в июле 2020 остался хвост. Проверь закрытие по договору и объекту расчетов.", + followupContext: null, + llmPreDecomposeMeta: null, + useMock: false + }); + + expect(decision.runAddressLane).toBe(false); + expect(decision.toolGateDecision).toBe("skip_address_lane"); + expect(decision.toolGateReason).toBe("deep_analysis_signal_fallback_to_deep"); + expect(decision.livingMode).toBe("deep_analysis"); + expect(decision.livingReason).toBe("deep_analysis_signal_fallback_to_deep"); + expect(decision.orchestrationContract?.deep_analysis_signal_fallback_to_deep).toBe(true); + }); }); diff --git a/llm_normalizer/backend/tests/assistantTurnRuntimeDepsAdapter.test.ts b/llm_normalizer/backend/tests/assistantTurnRuntimeDepsAdapter.test.ts index 0a8d860..1ace519 100644 --- a/llm_normalizer/backend/tests/assistantTurnRuntimeDepsAdapter.test.ts +++ b/llm_normalizer/backend/tests/assistantTurnRuntimeDepsAdapter.test.ts @@ -129,4 +129,89 @@ describe("assistant turn runtime deps adapter", () => { expect(deps.compactWhitespace(" value ")).toBe("value"); expect(helperCompactWhitespace).toHaveBeenCalledWith(" value "); }); + + it("preserves method context for stateful service instances", async () => { + class SessionStoreLike { + public calls: string[] = []; + public ensureSession(sessionId: string) { + this.calls.push(`ensure:${sessionId}`); + return { session_id: sessionId } as any; + } + public appendItem(sessionId: string) { + this.calls.push(`append:${sessionId}`); + } + public getSession(sessionId: string) { + this.calls.push(`get:${sessionId}`); + return null; + } + public setInvestigationState(sessionId: string) { + this.calls.push(`state:${sessionId}`); + return null; + } + } + + class SessionLoggerLike { + public persisted = 0; + public persistSession() { + this.persisted += 1; + } + } + + class NormalizerLike { + public normalized = 0; + public async normalize() { + this.normalized += 1; + return {}; + } + } + + const sessions = new SessionStoreLike(); + const sessionLogger = new SessionLoggerLike(); + const normalizerService = new NormalizerLike(); + + const deps = buildAssistantTurnRuntimeDeps({ + sessions, + sessionLogger, + normalizerService, + dataLayer: { + executeRouteRuntime: async () => ({}) + }, + addressQueryService: { + tryHandle: async () => null + }, + chatClient: {}, + messageIdFactory: () => "msg-ctx", + nowIso: () => "2026-04-11T00:00:00.000Z", + defaultApiKey: "", + logEvent: () => {}, + flags: { + featureAssistantAddressQueryV1: false, + featureAddressLlmPredecomposeV1: false, + featureInvestigationStateV1: false, + featureStateFollowupBindingV1: false, + featureContractsV11: false, + featureAnswerPolicyV11: false, + featureProblemCentricAnswerV1: false, + featureLifecycleAnswerV1: false + }, + defaults: { + defaultModel: "model", + defaultBaseUrl: "base" + }, + helpers: { + compactWhitespace: (value: unknown) => String(value ?? "") + } as any + }); + + deps.ensureSession("asst-ctx"); + deps.appendItem("asst-ctx", { role: "user" } as any); + deps.getSession("asst-ctx"); + deps.setInvestigationState("asst-ctx", null); + deps.persistSession({ session_id: "asst-ctx" } as any); + await deps.normalize({ user_message: "ctx" } as any); + + expect(sessions.calls).toEqual(["ensure:asst-ctx", "append:asst-ctx", "get:asst-ctx", "state:asst-ctx"]); + expect(sessionLogger.persisted).toBe(1); + expect(normalizerService.normalized).toBe(1); + }); }); diff --git a/llm_normalizer/backend/vitest-full-report.json b/llm_normalizer/backend/vitest-full-report.json new file mode 100644 index 0000000..fe05723 --- /dev/null +++ b/llm_normalizer/backend/vitest-full-report.json @@ -0,0 +1 @@ +{"numTotalTestSuites":251,"numPassedTestSuites":225,"numFailedTestSuites":26,"numPendingTestSuites":0,"numTotalTests":670,"numPassedTests":616,"numFailedTests":54,"numPendingTests":0,"numTodoTests":0,"snapshot":{"added":0,"failure":false,"filesAdded":0,"filesRemoved":0,"filesRemovedList":[],"filesUnmatched":0,"filesUpdated":0,"matched":0,"total":0,"unchecked":0,"uncheckedKeysByFile":[],"unmatched":0,"updated":0,"didUpdate":false},"startTime":1775902593352,"success":false,"testResults":[{"assertionResults":[{"ancestorTitles":["address MCP encoding repair"],"fullName":"address MCP encoding repair repairs UTF-8/CP1251 mojibake in object rows","status":"passed","title":"repairs UTF-8/CP1251 mojibake in object rows","duration":7.5242000000000075,"failureMessages":[],"meta":{}}],"startTime":1775902595151,"endTime":1775902595158.5242,"status":"passed","message":"","name":"X:/1C/NDC_1C/llm_normalizer/backend/tests/addressMcpClientEncoding.test.ts"},{"assertionResults":[{"ancestorTitles":["address query shape classifier"],"fullName":"address query shape classifier classifies explain question as deep-shape","status":"passed","title":"classifies explain question as deep-shape","duration":0.8351999999999862,"failureMessages":[],"meta":{}},{"ancestorTitles":["address query shape classifier"],"fullName":"address query shape classifier classifies aggregate lookup question","status":"passed","title":"classifies aggregate lookup question","duration":0.4757000000000744,"failureMessages":[],"meta":{}},{"ancestorTitles":["address query shape classifier"],"fullName":"address query shape classifier classifies compound factual question","status":"passed","title":"classifies compound factual question","duration":0.17849999999998545,"failureMessages":[],"meta":{}},{"ancestorTitles":["address query shape classifier"],"fullName":"address query shape classifier keeps company lookup phrasing in address lane","status":"passed","title":"keeps company lookup phrasing in address lane","duration":3.8835000000000264,"failureMessages":[],"meta":{}},{"ancestorTitles":["address query shape classifier"],"fullName":"address query shape classifier keeps loose by-anchor follow-up phrasing in address lane","status":"passed","title":"keeps loose by-anchor follow-up phrasing in address lane","duration":1.6160999999999603,"failureMessages":[],"meta":{}},{"ancestorTitles":["address query shape classifier"],"fullName":"address query shape classifier keeps slang transaction phrasing in address lane","status":"passed","title":"keeps slang transaction phrasing in address lane","duration":0.19669999999996435,"failureMessages":[],"meta":{}},{"ancestorTitles":["address query shape classifier"],"fullName":"address query shape classifier keeps short balance slang with compact account token in address lane","status":"passed","title":"keeps short balance slang with compact account token in address lane","duration":0.08789999999999054,"failureMessages":[],"meta":{}},{"ancestorTitles":["address query shape classifier"],"fullName":"address query shape classifier keeps management period profile question in address lane","status":"passed","title":"keeps management period profile question in address lane","duration":0.09390000000007603,"failureMessages":[],"meta":{}},{"ancestorTitles":["address query shape classifier"],"fullName":"address query shape classifier keeps management document/section profile question in address lane","status":"passed","title":"keeps management document/section profile question in address lane","duration":0.1790000000000873,"failureMessages":[],"meta":{}},{"ancestorTitles":["address query shape classifier"],"fullName":"address query shape classifier keeps management counterparty population question in address lane","status":"passed","title":"keeps management counterparty population question in address lane","duration":0.11519999999995889,"failureMessages":[],"meta":{}},{"ancestorTitles":["address query shape classifier"],"fullName":"address query shape classifier keeps slang supplier count question in address lane","status":"passed","title":"keeps slang supplier count question in address lane","duration":0.06069999999999709,"failureMessages":[],"meta":{}},{"ancestorTitles":["address query shape classifier"],"fullName":"address query shape classifier keeps slang client count question in address lane","status":"passed","title":"keeps slang client count question in address lane","duration":0.05119999999999436,"failureMessages":[],"meta":{}},{"ancestorTitles":["address query shape classifier"],"fullName":"address query shape classifier keeps customer activity lifecycle question in address lane","status":"passed","title":"keeps customer activity lifecycle question in address lane","duration":0.07370000000003074,"failureMessages":[],"meta":{}},{"ancestorTitles":["address query shape classifier"],"fullName":"address query shape classifier keeps customer list all-time question in address lane","status":"passed","title":"keeps customer list all-time question in address lane","duration":0.049999999999954525,"failureMessages":[],"meta":{}},{"ancestorTitles":["address query shape classifier"],"fullName":"address query shape classifier keeps customer list short-year question in address lane","status":"passed","title":"keeps customer list short-year question in address lane","duration":0.04469999999992069,"failureMessages":[],"meta":{}},{"ancestorTitles":["address query shape classifier"],"fullName":"address query shape classifier keeps noisy management phrase about years alive in address lane","status":"passed","title":"keeps noisy management phrase about years alive in address lane","duration":0.03880000000003747,"failureMessages":[],"meta":{}},{"ancestorTitles":["address query shape classifier"],"fullName":"address query shape classifier keeps noisy month-peak phrase in address lane","status":"passed","title":"keeps noisy month-peak phrase in address lane","duration":0.038399999999910506,"failureMessages":[],"meta":{}},{"ancestorTitles":["address query shape classifier"],"fullName":"address query shape classifier keeps management contract usage overview question in address lane","status":"passed","title":"keeps management contract usage overview question in address lane","duration":0.04529999999999745,"failureMessages":[],"meta":{}},{"ancestorTitles":["address query shape classifier"],"fullName":"address query shape classifier keeps customer value ranking question in address lane","status":"passed","title":"keeps customer value ranking question in address lane","duration":0.040300000000002,"failureMessages":[],"meta":{}},{"ancestorTitles":["address query shape classifier"],"fullName":"address query shape classifier keeps highest inflow slang question in address lane","status":"passed","title":"keeps highest inflow slang question in address lane","duration":0.040100000000052205,"failureMessages":[],"meta":{}},{"ancestorTitles":["address query shape classifier"],"fullName":"address query shape classifier keeps typo customer highest-check question in address lane","status":"passed","title":"keeps typo customer highest-check question in address lane","duration":0.035399999999981446,"failureMessages":[],"meta":{}},{"ancestorTitles":["address query shape classifier"],"fullName":"address query shape classifier keeps supplier payout ranking question in address lane","status":"passed","title":"keeps supplier payout ranking question in address lane","duration":0.03409999999996671,"failureMessages":[],"meta":{}},{"ancestorTitles":["address query shape classifier"],"fullName":"address query shape classifier keeps contract turnover ranking question in address lane","status":"passed","title":"keeps contract turnover ranking question in address lane","duration":0.04499999999995907,"failureMessages":[],"meta":{}},{"ancestorTitles":["address query shape classifier"],"fullName":"address query shape classifier keeps top contract wording with 'контракт' in address lane","status":"passed","title":"keeps top contract wording with 'контракт' in address lane","duration":0.04099999999993997,"failureMessages":[],"meta":{}},{"ancestorTitles":["address compose stage utf8 headers"],"fullName":"address compose stage utf8 headers renders readable russian header for contract document list","status":"passed","title":"renders readable russian header for contract document list","duration":1.0487999999999147,"failureMessages":[],"meta":{}},{"ancestorTitles":["address compose stage utf8 headers"],"fullName":"address compose stage utf8 headers renders readable russian header for contract bank operations","status":"passed","title":"renders readable russian header for contract bank operations","duration":0.06079999999997199,"failureMessages":[],"meta":{}},{"ancestorTitles":["address compose stage utf8 headers"],"fullName":"address compose stage utf8 headers renders readable russian header for contracts-by-counterparty list","status":"passed","title":"renders readable russian header for contracts-by-counterparty list","duration":0.10760000000004766,"failureMessages":[],"meta":{}},{"ancestorTitles":["address compose stage utf8 headers"],"fullName":"address compose stage utf8 headers renders period coverage summary for management profile intent","status":"passed","title":"renders period coverage summary for management profile intent","duration":0.33579999999994925,"failureMessages":[],"meta":{}},{"ancestorTitles":["address compose stage utf8 headers"],"fullName":"address compose stage utf8 headers renders document type + account section profile summary","status":"passed","title":"renders document type + account section profile summary","duration":0.32650000000001,"failureMessages":[],"meta":{}},{"ancestorTitles":["address compose stage utf8 headers"],"fullName":"address compose stage utf8 headers returns focused answer for active year question (without month block)","status":"passed","title":"returns focused answer for active year question (without month block)","duration":0.5487000000000535,"failureMessages":[],"meta":{}},{"ancestorTitles":["address compose stage utf8 headers"],"fullName":"address compose stage utf8 headers returns focused answer for active month question (without year block)","status":"passed","title":"returns focused answer for active month question (without year block)","duration":0.3705999999999676,"failureMessages":[],"meta":{}},{"ancestorTitles":["address compose stage utf8 headers"],"fullName":"address compose stage utf8 headers returns focused answer for passive year question (and ignores low-activity tail year)","status":"passed","title":"returns focused answer for passive year question (and ignores low-activity tail year)","duration":0.1351999999999407,"failureMessages":[],"meta":{}},{"ancestorTitles":["address compose stage utf8 headers"],"fullName":"address compose stage utf8 headers returns focused answer for passive month question (without year block)","status":"passed","title":"returns focused answer for passive month question (without year block)","duration":0.13160000000004857,"failureMessages":[],"meta":{}},{"ancestorTitles":["address compose stage utf8 headers"],"fullName":"address compose stage utf8 headers shows operational range and low-activity tail for coverage question","status":"passed","title":"shows operational range and low-activity tail for coverage question","duration":0.23839999999995598,"failureMessages":[],"meta":{}},{"ancestorTitles":["address compose stage utf8 headers"],"fullName":"address compose stage utf8 headers returns focused document-type answer without account sections","status":"passed","title":"returns focused document-type answer without account sections","duration":0.4957000000000562,"failureMessages":[],"meta":{}},{"ancestorTitles":["address compose stage utf8 headers"],"fullName":"address compose stage utf8 headers returns focused account-sections answer without document types","status":"passed","title":"returns focused account-sections answer without document types","duration":0.30760000000009313,"failureMessages":[],"meta":{}},{"ancestorTitles":["address compose stage utf8 headers"],"fullName":"address compose stage utf8 headers returns focused answer for rare document types question","status":"passed","title":"returns focused answer for rare document types question","duration":0.17709999999999582,"failureMessages":[],"meta":{}},{"ancestorTitles":["address compose stage utf8 headers"],"fullName":"address compose stage utf8 headers returns focused answer for least-filled account sections question","status":"passed","title":"returns focused answer for least-filled account sections question","duration":0.16789999999991778,"failureMessages":[],"meta":{}},{"ancestorTitles":["address compose stage utf8 headers"],"fullName":"address compose stage utf8 headers returns focused answer for total counterparties question","status":"passed","title":"returns focused answer for total counterparties question","duration":0.6945999999999231,"failureMessages":[],"meta":{}},{"ancestorTitles":["address compose stage utf8 headers"],"fullName":"address compose stage utf8 headers returns focused answer for counterparty roles split question","status":"passed","title":"returns focused answer for counterparty roles split question","duration":0.4030999999999949,"failureMessages":[],"meta":{}},{"ancestorTitles":["address compose stage utf8 headers"],"fullName":"address compose stage utf8 headers returns focused answer for slang supplier count question","status":"passed","title":"returns focused answer for slang supplier count question","duration":0.12260000000003402,"failureMessages":[],"meta":{}},{"ancestorTitles":["address compose stage utf8 headers"],"fullName":"address compose stage utf8 headers returns focused answer for slang client count question","status":"passed","title":"returns focused answer for slang client count question","duration":0.10110000000008768,"failureMessages":[],"meta":{}},{"ancestorTitles":["address compose stage utf8 headers"],"fullName":"address compose stage utf8 headers returns customer activity lifecycle list for year question","status":"passed","title":"returns customer activity lifecycle list for year question","duration":0.4954999999999927,"failureMessages":[],"meta":{}},{"ancestorTitles":["address compose stage utf8 headers"],"fullName":"address compose stage utf8 headers returns explicit 2020 year label for short-year lifecycle question","status":"passed","title":"returns explicit 2020 year label for short-year lifecycle question","duration":1.3813000000000102,"failureMessages":[],"meta":{}},{"ancestorTitles":["address compose stage utf8 headers"],"fullName":"address compose stage utf8 headers returns contract usage overview summary","status":"passed","title":"returns contract usage overview summary","duration":0.20000000000004547,"failureMessages":[],"meta":{}},{"ancestorTitles":["address compose stage utf8 headers"],"fullName":"address compose stage utf8 headers renders customer value top list with explicit top-2 limit","status":"passed","title":"renders customer value top list with explicit top-2 limit","duration":2.3671000000000504,"failureMessages":[],"meta":{}},{"ancestorTitles":["address compose stage utf8 headers"],"fullName":"address compose stage utf8 headers renders top incoming deals for highest inflow wording","status":"passed","title":"renders top incoming deals for highest inflow wording","duration":0.4516999999999598,"failureMessages":[],"meta":{}},{"ancestorTitles":["address compose stage utf8 headers"],"fullName":"address compose stage utf8 headers renders max-single ranking for highest-check typo wording","status":"passed","title":"renders max-single ranking for highest-check typo wording","duration":0.15359999999998308,"failureMessages":[],"meta":{}},{"ancestorTitles":["address compose stage utf8 headers"],"fullName":"address compose stage utf8 headers renders supplier payout list by operations count","status":"passed","title":"renders supplier payout list by operations count","duration":0.3366000000000895,"failureMessages":[],"meta":{}},{"ancestorTitles":["address compose stage utf8 headers"],"fullName":"address compose stage utf8 headers renders contract value list for minimal active budgets","status":"passed","title":"renders contract value list for minimal active budgets","duration":0.4270000000000209,"failureMessages":[],"meta":{}},{"ancestorTitles":["address compose stage utf8 headers"],"fullName":"address compose stage utf8 headers adds deterministic why-zero explanation for VAT forecast follow-up wording","status":"passed","title":"adds deterministic why-zero explanation for VAT forecast follow-up wording","duration":0.4777000000000271,"failureMessages":[],"meta":{}},{"ancestorTitles":["address compose stage utf8 headers"],"fullName":"address compose stage utf8 headers adds VAT declaration and payment deadlines for as-of-date forecast window","status":"passed","title":"adds VAT declaration and payment deadlines for as-of-date forecast window","duration":0.9346000000000458,"failureMessages":[],"meta":{}},{"ancestorTitles":["address compose stage utf8 headers"],"fullName":"address compose stage utf8 headers builds VAT deadlines correctly for Q4 with next-year rollover","status":"passed","title":"builds VAT deadlines correctly for Q4 with next-year rollover","duration":0.20539999999994052,"failureMessages":[],"meta":{}},{"ancestorTitles":["address compose stage utf8 headers"],"fullName":"address compose stage utf8 headers explains zero VAT as no-movements case when VAT turnovers are absent in window","status":"passed","title":"explains zero VAT as no-movements case when VAT turnovers are absent in window","duration":0.15999999999996817,"failureMessages":[],"meta":{}},{"ancestorTitles":["address compose stage utf8 headers"],"fullName":"address compose stage utf8 headers explains zero VAT as offset case when VAT turnovers exist but net is near zero","status":"passed","title":"explains zero VAT as offset case when VAT turnovers exist but net is near zero","duration":0.1352000000000544,"failureMessages":[],"meta":{}},{"ancestorTitles":["address intent resolver expansion (M2.3a)"],"fullName":"address intent resolver expansion (M2.3a) resolves documents by counterparty intent","status":"passed","title":"resolves documents by counterparty intent","duration":6.501099999999951,"failureMessages":[],"meta":{}},{"ancestorTitles":["address intent resolver expansion (M2.3a)"],"fullName":"address intent resolver expansion (M2.3a) resolves bank operations by counterparty intent","status":"passed","title":"resolves bank operations by counterparty intent","duration":1.619899999999916,"failureMessages":[],"meta":{}},{"ancestorTitles":["address intent resolver expansion (M2.3a)"],"fullName":"address intent resolver expansion (M2.3a) resolves documents forming balance intent","status":"passed","title":"resolves documents forming balance intent","duration":0.15660000000002583,"failureMessages":[],"meta":{}},{"ancestorTitles":["address intent resolver expansion (M2.3a)"],"fullName":"address intent resolver expansion (M2.3a) resolves documents forming balance for russian participle phrasing","status":"passed","title":"resolves documents forming balance for russian participle phrasing","duration":1.1416000000000395,"failureMessages":[],"meta":{}},{"ancestorTitles":["address intent resolver expansion (M2.3a)"],"fullName":"address intent resolver expansion (M2.3a) resolves documents forming balance for slang phrase with compact account token","status":"passed","title":"resolves documents forming balance for slang phrase with compact account token","duration":0.0968000000000302,"failureMessages":[],"meta":{}},{"ancestorTitles":["address intent resolver expansion (M2.3a)"],"fullName":"address intent resolver expansion (M2.3a) resolves documents forming balance for 'доки под остатком' slang phrase","status":"passed","title":"resolves documents forming balance for 'доки под остатком' slang phrase","duration":0.08529999999996107,"failureMessages":[],"meta":{}},{"ancestorTitles":["address intent resolver expansion (M2.3a)"],"fullName":"address intent resolver expansion (M2.3a) resolves documents by company phrase as counterparty intent","status":"passed","title":"resolves documents by company phrase as counterparty intent","duration":3.1820999999999913,"failureMessages":[],"meta":{}},{"ancestorTitles":["address intent resolver expansion (M2.3a)"],"fullName":"address intent resolver expansion (M2.3a) resolves transliterated docy slang as documents by counterparty intent","status":"passed","title":"resolves transliterated docy slang as documents by counterparty intent","duration":0.42399999999997817,"failureMessages":[],"meta":{}},{"ancestorTitles":["address intent resolver expansion (M2.3a)"],"fullName":"address intent resolver expansion (M2.3a) resolves bank operations by supplier phrase","status":"passed","title":"resolves bank operations by supplier phrase","duration":0.5025000000000546,"failureMessages":[],"meta":{}},{"ancestorTitles":["address intent resolver expansion (M2.3a)"],"fullName":"address intent resolver expansion (M2.3a) resolves documents by contract intent","status":"passed","title":"resolves documents by contract intent","duration":0.6798999999999751,"failureMessages":[],"meta":{}},{"ancestorTitles":["address intent resolver expansion (M2.3a)"],"fullName":"address intent resolver expansion (M2.3a) resolves bank operations by contract intent","status":"passed","title":"resolves bank operations by contract intent","duration":1.09050000000002,"failureMessages":[],"meta":{}},{"ancestorTitles":["address intent resolver expansion (M2.3a)"],"fullName":"address intent resolver expansion (M2.3a) resolves shorthand bank-by-contract slang intent","status":"passed","title":"resolves shorthand bank-by-contract slang intent","duration":0.2258000000000493,"failureMessages":[],"meta":{}},{"ancestorTitles":["address intent resolver expansion (M2.3a)"],"fullName":"address intent resolver expansion (M2.3a) resolves debt-by-contract query to open items intent","status":"passed","title":"resolves debt-by-contract query to open items intent","duration":0.2216999999999416,"failureMessages":[],"meta":{}},{"ancestorTitles":["address intent resolver expansion (M2.3a)"],"fullName":"address intent resolver expansion (M2.3a) resolves unclosed contracts list query without specific anchor","status":"passed","title":"resolves unclosed contracts list query without specific anchor","duration":0.22839999999996508,"failureMessages":[],"meta":{}},{"ancestorTitles":["address intent resolver expansion (M2.3a)"],"fullName":"address intent resolver expansion (M2.3a) resolves bank operations by contract for normalized phrase with linked contract wording","status":"passed","title":"resolves bank operations by contract for normalized phrase with linked contract wording","duration":0.22830000000010386,"failureMessages":[],"meta":{}},{"ancestorTitles":["address intent resolver expansion (M2.3a)"],"fullName":"address intent resolver expansion (M2.3a) keeps bank_operations_by_counterparty even when account hints are present","status":"passed","title":"keeps bank_operations_by_counterparty even when account hints are present","duration":0.47509999999999764,"failureMessages":[],"meta":{}},{"ancestorTitles":["address intent resolver expansion (M2.3a)"],"fullName":"address intent resolver expansion (M2.3a) resolves documents by client phrase","status":"passed","title":"resolves documents by client phrase","duration":0.25940000000002783,"failureMessages":[],"meta":{}},{"ancestorTitles":["address intent resolver expansion (M2.3a)"],"fullName":"address intent resolver expansion (M2.3a) resolves short slang docs phrase with loose by-anchor","status":"passed","title":"resolves short slang docs phrase with loose by-anchor","duration":0.155399999999986,"failureMessages":[],"meta":{}},{"ancestorTitles":["address intent resolver expansion (M2.3a)"],"fullName":"address intent resolver expansion (M2.3a) resolves typo slang docs phrase with implicit anchor","status":"passed","title":"resolves typo slang docs phrase with implicit anchor","duration":0.2685000000000173,"failureMessages":[],"meta":{}},{"ancestorTitles":["address intent resolver expansion (M2.3a)"],"fullName":"address intent resolver expansion (M2.3a) resolves noisy docs phrase with slang tail","status":"passed","title":"resolves noisy docs phrase with slang tail","duration":0.16179999999997108,"failureMessages":[],"meta":{}},{"ancestorTitles":["address intent resolver expansion (M2.3a)"],"fullName":"address intent resolver expansion (M2.3a) resolves slang transactions phrase by counterparty","status":"passed","title":"resolves slang transactions phrase by counterparty","duration":0.2518999999999778,"failureMessages":[],"meta":{}},{"ancestorTitles":["address intent resolver expansion (M2.3a)"],"fullName":"address intent resolver expansion (M2.3a) resolves short balance slang with compact account token","status":"passed","title":"resolves short balance slang with compact account token","duration":0.5275000000000318,"failureMessages":[],"meta":{}},{"ancestorTitles":["address intent resolver expansion (M2.3a)"],"fullName":"address intent resolver expansion (M2.3a) resolves colloquial 'что на счете' phrasing as account balance snapshot","status":"passed","title":"resolves colloquial 'что на счете' phrasing as account balance snapshot","duration":2.2480000000000473,"failureMessages":[],"meta":{}},{"ancestorTitles":["address intent resolver expansion (M2.3a)"],"fullName":"address intent resolver expansion (M2.3a) resolves mixed ru/en balance phrasing with account token","status":"passed","title":"resolves mixed ru/en balance phrasing with account token","duration":0.904700000000048,"failureMessages":[],"meta":{}},{"ancestorTitles":["address intent resolver expansion (M2.3a)"],"fullName":"address intent resolver expansion (M2.3a) resolves 'по докам' slang as documents forming balance","status":"passed","title":"resolves 'по докам' slang as documents forming balance","duration":0.12049999999999272,"failureMessages":[],"meta":{}},{"ancestorTitles":["address intent resolver expansion (M2.3a)"],"fullName":"address intent resolver expansion (M2.3a) resolves english compact docs-forming phrasing","status":"passed","title":"resolves english compact docs-forming phrasing","duration":0.0725999999999658,"failureMessages":[],"meta":{}},{"ancestorTitles":["address intent resolver expansion (M2.3a)"],"fullName":"address intent resolver expansion (M2.3a) resolves loose by-anchor follow-up as documents by counterparty fallback","status":"passed","title":"resolves loose by-anchor follow-up as documents by counterparty fallback","duration":0.6623000000000729,"failureMessages":[],"meta":{}},{"ancestorTitles":["address intent resolver expansion (M2.3a)"],"fullName":"address intent resolver expansion (M2.3a) resolves period coverage profile for years-in-database question","status":"passed","title":"resolves period coverage profile for years-in-database question","duration":0.2442999999999529,"failureMessages":[],"meta":{}},{"ancestorTitles":["address intent resolver expansion (M2.3a)"],"fullName":"address intent resolver expansion (M2.3a) resolves period coverage profile for top active year by documents question","status":"passed","title":"resolves period coverage profile for top active year by documents question","duration":0.13400000000001455,"failureMessages":[],"meta":{}},{"ancestorTitles":["address intent resolver expansion (M2.3a)"],"fullName":"address intent resolver expansion (M2.3a) resolves period coverage profile for top active month by operations question","status":"passed","title":"resolves period coverage profile for top active month by operations question","duration":0.12849999999991724,"failureMessages":[],"meta":{}},{"ancestorTitles":["address intent resolver expansion (M2.3a)"],"fullName":"address intent resolver expansion (M2.3a) resolves period coverage profile for passive year by documents question","status":"passed","title":"resolves period coverage profile for passive year by documents question","duration":0.10939999999993688,"failureMessages":[],"meta":{}},{"ancestorTitles":["address intent resolver expansion (M2.3a)"],"fullName":"address intent resolver expansion (M2.3a) resolves period coverage profile for passive month by operations question","status":"passed","title":"resolves period coverage profile for passive month by operations question","duration":0.10979999999995016,"failureMessages":[],"meta":{}},{"ancestorTitles":["address intent resolver expansion (M2.3a)"],"fullName":"address intent resolver expansion (M2.3a) resolves period coverage profile for noisy active-year-by-docs phrase","status":"passed","title":"resolves period coverage profile for noisy active-year-by-docs phrase","duration":0.0808999999999287,"failureMessages":[],"meta":{}},{"ancestorTitles":["address intent resolver expansion (M2.3a)"],"fullName":"address intent resolver expansion (M2.3a) resolves period coverage profile for month-peak follow-up phrase","status":"passed","title":"resolves period coverage profile for month-peak follow-up phrase","duration":0.07600000000002183,"failureMessages":[],"meta":{}},{"ancestorTitles":["address intent resolver expansion (M2.3a)"],"fullName":"address intent resolver expansion (M2.3a) resolves document+section profile for document type usage question","status":"passed","title":"resolves document+section profile for document type usage question","duration":0.08540000000004966,"failureMessages":[],"meta":{}},{"ancestorTitles":["address intent resolver expansion (M2.3a)"],"fullName":"address intent resolver expansion (M2.3a) resolves document+section profile for account section fill question","status":"passed","title":"resolves document+section profile for account section fill question","duration":0.09569999999996526,"failureMessages":[],"meta":{}},{"ancestorTitles":["address intent resolver expansion (M2.3a)"],"fullName":"address intent resolver expansion (M2.3a) resolves document+section profile for rare document types question","status":"passed","title":"resolves document+section profile for rare document types question","duration":0.07410000000004402,"failureMessages":[],"meta":{}},{"ancestorTitles":["address intent resolver expansion (M2.3a)"],"fullName":"address intent resolver expansion (M2.3a) resolves document+section profile for least-filled account sections question","status":"passed","title":"resolves document+section profile for least-filled account sections question","duration":0.06609999999989213,"failureMessages":[],"meta":{}},{"ancestorTitles":["address intent resolver expansion (M2.3a)"],"fullName":"address intent resolver expansion (M2.3a) resolves document+section profile for noisy docs usage phrase","status":"passed","title":"resolves document+section profile for noisy docs usage phrase","duration":0.06729999999993197,"failureMessages":[],"meta":{}},{"ancestorTitles":["address intent resolver expansion (M2.3a)"],"fullName":"address intent resolver expansion (M2.3a) resolves document+section profile for summary by doc types and share phrase","status":"passed","title":"resolves document+section profile for summary by doc types and share phrase","duration":0.07929999999998927,"failureMessages":[],"meta":{}},{"ancestorTitles":["address intent resolver expansion (M2.3a)"],"fullName":"address intent resolver expansion (M2.3a) resolves counterparty population intent for total unique counterparties question","status":"passed","title":"resolves counterparty population intent for total unique counterparties question","duration":0.07740000000001146,"failureMessages":[],"meta":{}},{"ancestorTitles":["address intent resolver expansion (M2.3a)"],"fullName":"address intent resolver expansion (M2.3a) resolves counterparty population intent for roles split question","status":"passed","title":"resolves counterparty population intent for roles split question","duration":0.08379999999999654,"failureMessages":[],"meta":{}},{"ancestorTitles":["address intent resolver expansion (M2.3a)"],"fullName":"address intent resolver expansion (M2.3a) resolves counterparty population intent for slang supplier count question","status":"passed","title":"resolves counterparty population intent for slang supplier count question","duration":0.07230000000004111,"failureMessages":[],"meta":{}},{"ancestorTitles":["address intent resolver expansion (M2.3a)"],"fullName":"address intent resolver expansion (M2.3a) resolves counterparty population intent for slang supplier count in base question","status":"passed","title":"resolves counterparty population intent for slang supplier count in base question","duration":0.07159999999998945,"failureMessages":[],"meta":{}},{"ancestorTitles":["address intent resolver expansion (M2.3a)"],"fullName":"address intent resolver expansion (M2.3a) resolves counterparty population intent for slang client count question","status":"passed","title":"resolves counterparty population intent for slang client count question","duration":0.0585999999999558,"failureMessages":[],"meta":{}},{"ancestorTitles":["address intent resolver expansion (M2.3a)"],"fullName":"address intent resolver expansion (M2.3a) resolves counterparty population intent for slang client count in base question","status":"passed","title":"resolves counterparty population intent for slang client count in base question","duration":0.06009999999992033,"failureMessages":[],"meta":{}},{"ancestorTitles":["address intent resolver expansion (M2.3a)"],"fullName":"address intent resolver expansion (M2.3a) resolves counterparty lifecycle intent for active customers in year question","status":"passed","title":"resolves counterparty lifecycle intent for active customers in year question","duration":0.09109999999998308,"failureMessages":[],"meta":{}},{"ancestorTitles":["address intent resolver expansion (M2.3a)"],"fullName":"address intent resolver expansion (M2.3a) resolves counterparty lifecycle intent for active customers all-time question","status":"passed","title":"resolves counterparty lifecycle intent for active customers all-time question","duration":0.07650000000001,"failureMessages":[],"meta":{}},{"ancestorTitles":["address intent resolver expansion (M2.3a)"],"fullName":"address intent resolver expansion (M2.3a) resolves counterparty lifecycle intent for customer list all-time question","status":"passed","title":"resolves counterparty lifecycle intent for customer list all-time question","duration":0.07730000000003656,"failureMessages":[],"meta":{}},{"ancestorTitles":["address intent resolver expansion (M2.3a)"],"fullName":"address intent resolver expansion (M2.3a) resolves counterparty lifecycle intent for customer list short-year question","status":"passed","title":"resolves counterparty lifecycle intent for customer list short-year question","duration":0.07449999999994361,"failureMessages":[],"meta":{}},{"ancestorTitles":["address intent resolver expansion (M2.3a)"],"fullName":"address intent resolver expansion (M2.3a) resolves counterparty lifecycle intent for roster wording without explicit period","status":"passed","title":"resolves counterparty lifecycle intent for roster wording without explicit period","duration":0.08420000000000982,"failureMessages":[],"meta":{}},{"ancestorTitles":["address intent resolver expansion (M2.3a)"],"fullName":"address intent resolver expansion (M2.3a) resolves counterparty lifecycle intent for one-time counterparties wording","status":"passed","title":"resolves counterparty lifecycle intent for one-time counterparties wording","duration":0.08730000000002747,"failureMessages":[],"meta":{}},{"ancestorTitles":["address intent resolver expansion (M2.3a)"],"fullName":"address intent resolver expansion (M2.3a) resolves counterparty lifecycle intent for longest-running counterparties wording","status":"passed","title":"resolves counterparty lifecycle intent for longest-running counterparties wording","duration":0.08030000000007931,"failureMessages":[],"meta":{}},{"ancestorTitles":["address intent resolver expansion (M2.3a)"],"fullName":"address intent resolver expansion (M2.3a) resolves supplier lifecycle segmentation wording into lifecycle intent","status":"passed","title":"resolves supplier lifecycle segmentation wording into lifecycle intent","duration":0.15220000000010714,"failureMessages":[],"meta":{}},{"ancestorTitles":["address intent resolver expansion (M2.3a)"],"fullName":"address intent resolver expansion (M2.3a) resolves stale suppliers wording into lifecycle intent","status":"passed","title":"resolves stale suppliers wording into lifecycle intent","duration":0.12619999999992615,"failureMessages":[],"meta":{}},{"ancestorTitles":["address intent resolver expansion (M2.3a)"],"fullName":"address intent resolver expansion (M2.3a) keeps supplier lifecycle segmentation with operations wording in lifecycle intent","status":"passed","title":"keeps supplier lifecycle segmentation with operations wording in lifecycle intent","duration":0.10990000000003874,"failureMessages":[],"meta":{}},{"ancestorTitles":["address intent resolver expansion (M2.3a)"],"fullName":"address intent resolver expansion (M2.3a) keeps stale supplier operations wording in lifecycle intent","status":"passed","title":"keeps stale supplier operations wording in lifecycle intent","duration":0.09149999999999636,"failureMessages":[],"meta":{}},{"ancestorTitles":["address intent resolver expansion (M2.3a)"],"fullName":"address intent resolver expansion (M2.3a) keeps slang all-customers-all-time wording in lifecycle intent","status":"passed","title":"keeps slang all-customers-all-time wording in lifecycle intent","duration":0.08199999999999363,"failureMessages":[],"meta":{}},{"ancestorTitles":["address intent resolver expansion (M2.3a)"],"fullName":"address intent resolver expansion (M2.3a) keeps churn wording with year in lifecycle intent","status":"passed","title":"keeps churn wording with year in lifecycle intent","duration":0.07719999999994798,"failureMessages":[],"meta":{}},{"ancestorTitles":["address intent resolver expansion (M2.3a)"],"fullName":"address intent resolver expansion (M2.3a) keeps one-time-plus-churn wording in lifecycle intent","status":"passed","title":"keeps one-time-plus-churn wording in lifecycle intent","duration":0.07489999999995689,"failureMessages":[],"meta":{}},{"ancestorTitles":["address intent resolver expansion (M2.3a)"],"fullName":"address intent resolver expansion (M2.3a) keeps oldest-collaboration slang wording in lifecycle intent","status":"passed","title":"keeps oldest-collaboration slang wording in lifecycle intent","duration":0.08199999999999363,"failureMessages":[],"meta":{}},{"ancestorTitles":["address intent resolver expansion (M2.3a)"],"fullName":"address intent resolver expansion (M2.3a) keeps regular-vs-one-off supplier slang in lifecycle intent (not population)","status":"passed","title":"keeps regular-vs-one-off supplier slang in lifecycle intent (not population)","duration":0.07960000000002765,"failureMessages":[],"meta":{}},{"ancestorTitles":["address intent resolver expansion (M2.3a)"],"fullName":"address intent resolver expansion (M2.3a) resolves contract usage overview intent","status":"passed","title":"resolves contract usage overview intent","duration":0.09709999999995489,"failureMessages":[],"meta":{}},{"ancestorTitles":["address intent resolver expansion (M2.3a)"],"fullName":"address intent resolver expansion (M2.3a) resolves stale contracts wording into contract usage overview intent","status":"passed","title":"resolves stale contracts wording into contract usage overview intent","duration":0.14419999999995525,"failureMessages":[],"meta":{}},{"ancestorTitles":["address intent resolver expansion (M2.3a)"],"fullName":"address intent resolver expansion (M2.3a) resolves customer revenue/payout ranking intent","status":"passed","title":"resolves customer revenue/payout ranking intent","duration":0.15030000000001564,"failureMessages":[],"meta":{}},{"ancestorTitles":["address intent resolver expansion (M2.3a)"],"fullName":"address intent resolver expansion (M2.3a) resolves major-share revenue wording into customer revenue intent","status":"passed","title":"resolves major-share revenue wording into customer revenue intent","duration":0.1568000000000893,"failureMessages":[],"meta":{}},{"ancestorTitles":["address intent resolver expansion (M2.3a)"],"fullName":"address intent resolver expansion (M2.3a) resolves customer revenue intent from highest inflow slang wording","status":"passed","title":"resolves customer revenue intent from highest inflow slang wording","duration":0.11360000000001946,"failureMessages":[],"meta":{}},{"ancestorTitles":["address intent resolver expansion (M2.3a)"],"fullName":"address intent resolver expansion (M2.3a) resolves customer revenue intent from small deals by budget slang wording","status":"passed","title":"resolves customer revenue intent from small deals by budget slang wording","duration":0.2898999999999887,"failureMessages":[],"meta":{}},{"ancestorTitles":["address intent resolver expansion (M2.3a)"],"fullName":"address intent resolver expansion (M2.3a) resolves customer revenue intent from typo highest-check wording","status":"passed","title":"resolves customer revenue intent from typo highest-check wording","duration":0.13390000000003965,"failureMessages":[],"meta":{}},{"ancestorTitles":["address intent resolver expansion (M2.3a)"],"fullName":"address intent resolver expansion (M2.3a) resolves top counterparty slang wording into customer revenue intent","status":"passed","title":"resolves top counterparty slang wording into customer revenue intent","duration":0.13139999999998508,"failureMessages":[],"meta":{}},{"ancestorTitles":["address intent resolver expansion (M2.3a)"],"fullName":"address intent resolver expansion (M2.3a) resolves supplier payouts profile intent from slang wording","status":"passed","title":"resolves supplier payouts profile intent from slang wording","duration":0.13979999999992287,"failureMessages":[],"meta":{}},{"ancestorTitles":["address intent resolver expansion (M2.3a)"],"fullName":"address intent resolver expansion (M2.3a) resolves contract usage and value intent","status":"passed","title":"resolves contract usage and value intent","duration":0.08229999999991833,"failureMessages":[],"meta":{}},{"ancestorTitles":["address intent resolver expansion (M2.3a)"],"fullName":"address intent resolver expansion (M2.3a) resolves top contract wording with 'контракт' into contract usage and value intent","status":"passed","title":"resolves top contract wording with 'контракт' into contract usage and value intent","duration":0.10310000000004038,"failureMessages":[],"meta":{}},{"ancestorTitles":["address intent resolver expansion (M2.3a)"],"fullName":"address intent resolver expansion (M2.3a) resolves revenue-total slang wording into customer revenue intent","status":"passed","title":"resolves revenue-total slang wording into customer revenue intent","duration":0.116800000000012,"failureMessages":[],"meta":{}},{"ancestorTitles":["address intent resolver expansion (M2.3a)"],"fullName":"address intent resolver expansion (M2.3a) resolves overall-turnover wording into customer revenue intent","status":"passed","title":"resolves overall-turnover wording into customer revenue intent","duration":0.11019999999996344,"failureMessages":[],"meta":{}},{"ancestorTitles":["address intent resolver expansion (M2.3a)"],"fullName":"address intent resolver expansion (M2.3a) resolves VAT payment forecast wording into dedicated VAT forecast intent","status":"passed","title":"resolves VAT payment forecast wording into dedicated VAT forecast intent","duration":0.5724999999999909,"failureMessages":[],"meta":{}},{"ancestorTitles":["address intent resolver expansion (M2.3a)"],"fullName":"address intent resolver expansion (M2.3a) resolves colloquial VAT payable estimate wording without explicit 'прогноз'","status":"passed","title":"resolves colloquial VAT payable estimate wording without explicit 'прогноз'","duration":0.13049999999998363,"failureMessages":[],"meta":{}},{"ancestorTitles":["address intent resolver expansion (M2.3a)"],"fullName":"address intent resolver expansion (M2.3a) resolves multi-contract counterparties wording into contract usage and value intent","status":"passed","title":"resolves multi-contract counterparties wording into contract usage and value intent","duration":0.12990000000002055,"failureMessages":[],"meta":{}},{"ancestorTitles":["address intent resolver expansion (M2.3a)"],"fullName":"address intent resolver expansion (M2.3a) resolves contracts-by-counterparty intent from list wording","status":"passed","title":"resolves contracts-by-counterparty intent from list wording","duration":0.22800000000006548,"failureMessages":[],"meta":{}},{"ancestorTitles":["address intent resolver expansion (M2.3a)"],"fullName":"address intent resolver expansion (M2.3a) prefers documents-by-contract intent for explicit document follow-up wording","status":"passed","title":"prefers documents-by-contract intent for explicit document follow-up wording","duration":0.09249999999997272,"failureMessages":[],"meta":{}},{"ancestorTitles":["address intent resolver expansion (M2.3a)"],"fullName":"address intent resolver expansion (M2.3a) routes supplier tail-risk wording into payables intent","status":"passed","title":"routes supplier tail-risk wording into payables intent","duration":0.07029999999997472,"failureMessages":[],"meta":{}},{"ancestorTitles":["address intent resolver expansion (M2.3a)"],"fullName":"address intent resolver expansion (M2.3a) keeps out-of-scope supplier control wording as unknown intent","status":"passed","title":"keeps out-of-scope supplier control wording as unknown intent","duration":0.25480000000004566,"failureMessages":[],"meta":{}},{"ancestorTitles":["address intent resolver expansion (M2.3a)"],"fullName":"address intent resolver expansion (M2.3a) routes long shipment-to-payment lag wording into receivables intent","status":"passed","title":"routes long shipment-to-payment lag wording into receivables intent","duration":0.07589999999993324,"failureMessages":[],"meta":{}},{"ancestorTitles":["address intent resolver expansion (M2.3a)"],"fullName":"address intent resolver expansion (M2.3a) routes non-paying counterparties month-risk wording into receivables intent","status":"passed","title":"routes non-paying counterparties month-risk wording into receivables intent","duration":0.05560000000002674,"failureMessages":[],"meta":{}},{"ancestorTitles":["address intent resolver expansion (M2.3a)"],"fullName":"address intent resolver expansion (M2.3a) routes reconciliation mismatch wording into open contracts intent","status":"passed","title":"routes reconciliation mismatch wording into open contracts intent","duration":0.05349999999998545,"failureMessages":[],"meta":{}},{"ancestorTitles":["address intent resolver expansion (M2.3a)"],"fullName":"address intent resolver expansion (M2.3a) routes reconciliation mismatch wording without explicit lookup verb into open contracts intent","status":"passed","title":"routes reconciliation mismatch wording without explicit lookup verb into open contracts intent","duration":0.0544999999999618,"failureMessages":[],"meta":{}},{"ancestorTitles":["address intent resolver expansion (M2.3a)"],"fullName":"address intent resolver expansion (M2.3a) routes payments-without-closing-docs wording into open contracts intent","status":"passed","title":"routes payments-without-closing-docs wording into open contracts intent","duration":0.10310000000004038,"failureMessages":[],"meta":{}},{"ancestorTitles":["address intent resolver expansion (M2.3a)"],"fullName":"address intent resolver expansion (M2.3a) routes documents-without-payments wording into open contracts intent","status":"passed","title":"routes documents-without-payments wording into open contracts intent","duration":0.09420000000000073,"failureMessages":[],"meta":{}},{"ancestorTitles":["address intent resolver expansion (M2.3a)"],"fullName":"address intent resolver expansion (M2.3a) routes stale advances without closing docs wording into open contracts intent","status":"passed","title":"routes stale advances without closing docs wording into open contracts intent","duration":0.18420000000003256,"failureMessages":[],"meta":{}},{"ancestorTitles":["address intent resolver expansion (M2.3a)"],"fullName":"address intent resolver expansion (M2.3a) routes buyers with open debt wording into open-items intent","status":"passed","title":"routes buyers with open debt wording into open-items intent","duration":0.14210000000002765,"failureMessages":[],"meta":{}},{"ancestorTitles":["address filter extraction for balance drilldown"],"fullName":"address filter extraction for balance drilldown does not force default limit=20 for management aggregate intents","status":"passed","title":"does not force default limit=20 for management aggregate intents","duration":7.040200000000027,"failureMessages":[],"meta":{}},{"ancestorTitles":["address filter extraction for balance drilldown"],"fullName":"address filter extraction for balance drilldown extracts short-year period for lifecycle customer list question","status":"passed","title":"extracts short-year period for lifecycle customer list question","duration":0.1468000000000984,"failureMessages":[],"meta":{}},{"ancestorTitles":["address filter extraction for balance drilldown"],"fullName":"address filter extraction for balance drilldown drops noisy counterparty anchor in ranking question for customer revenue profile","status":"passed","title":"drops noisy counterparty anchor in ranking question for customer revenue profile","duration":2.531600000000026,"failureMessages":[],"meta":{}},{"ancestorTitles":["address filter extraction for balance drilldown"],"fullName":"address filter extraction for balance drilldown does not derive fake counterparty anchor for open-contracts stale-advance wording","status":"passed","title":"does not derive fake counterparty anchor for open-contracts stale-advance wording","duration":0.1795000000000755,"failureMessages":[],"meta":{}},{"ancestorTitles":["address filter extraction for balance drilldown"],"fullName":"address filter extraction for balance drilldown derives VAT forecast quarter-to-date window when plain date phrase is present","status":"passed","title":"derives VAT forecast quarter-to-date window when plain date phrase is present","duration":0.2601000000000795,"failureMessages":[],"meta":{}},{"ancestorTitles":["address filter extraction for balance drilldown"],"fullName":"address filter extraction for balance drilldown derives VAT forecast quarter-to-date window for explicit day+month+year phrase","status":"passed","title":"derives VAT forecast quarter-to-date window for explicit day+month+year phrase","duration":0.1776999999999589,"failureMessages":[],"meta":{}},{"ancestorTitles":["address filter extraction for balance drilldown"],"fullName":"address filter extraction for balance drilldown derives VAT forecast quarter-to-date window when strict as-of cue is present","status":"passed","title":"derives VAT forecast quarter-to-date window when strict as-of cue is present","duration":0.3543000000000802,"failureMessages":[],"meta":{}},{"ancestorTitles":["address filter extraction for balance drilldown"],"fullName":"address filter extraction for balance drilldown defaults as_of_date for documents_forming_balance when date is omitted","status":"passed","title":"defaults as_of_date for documents_forming_balance when date is omitted","duration":1.4861000000000786,"failureMessages":[],"meta":{}},{"ancestorTitles":["address filter extraction for balance drilldown"],"fullName":"address filter extraction for balance drilldown cuts period tail from counterparty anchor","status":"passed","title":"cuts period tail from counterparty anchor","duration":0.9506999999999834,"failureMessages":[],"meta":{}},{"ancestorTitles":["address filter extraction for balance drilldown"],"fullName":"address filter extraction for balance drilldown cuts all-time tail from counterparty anchor and skips 90-day default window","status":"passed","title":"cuts all-time tail from counterparty anchor and skips 90-day default window","duration":0.484299999999962,"failureMessages":[],"meta":{}},{"ancestorTitles":["address filter extraction for balance drilldown"],"fullName":"address filter extraction for balance drilldown keeps all-time period by default for counterparty docs query without explicit window","status":"passed","title":"keeps all-time period by default for counterparty docs query without explicit window","duration":0.1994999999999436,"failureMessages":[],"meta":{}},{"ancestorTitles":["address filter extraction for balance drilldown"],"fullName":"address filter extraction for balance drilldown extracts counterparty from company phrase and derives year period","status":"passed","title":"extracts counterparty from company phrase and derives year period","duration":0.17349999999999,"failureMessages":[],"meta":{}},{"ancestorTitles":["address filter extraction for balance drilldown"],"fullName":"address filter extraction for balance drilldown extracts counterparty from supplier phrase and derives month period","status":"passed","title":"extracts counterparty from supplier phrase and derives month period","duration":0.12350000000003547,"failureMessages":[],"meta":{}},{"ancestorTitles":["address filter extraction for balance drilldown"],"fullName":"address filter extraction for balance drilldown cuts period-end tail from counterparty anchor and keeps as_of for open-items query","status":"passed","title":"cuts period-end tail from counterparty anchor and keeps as_of for open-items query","duration":0.13139999999998508,"failureMessages":[],"meta":{}},{"ancestorTitles":["address filter extraction for balance drilldown"],"fullName":"address filter extraction for balance drilldown cuts report-date tail from counterparty anchor and keeps clean as_of filter","status":"passed","title":"cuts report-date tail from counterparty anchor and keeps clean as_of filter","duration":0.0925000000000864,"failureMessages":[],"meta":{}},{"ancestorTitles":["address filter extraction for balance drilldown"],"fullName":"address filter extraction for balance drilldown derives month period for balance snapshot from 'на май 2020'","status":"passed","title":"derives month period for balance snapshot from 'на май 2020'","duration":0.1188000000000784,"failureMessages":[],"meta":{}},{"ancestorTitles":["address filter extraction for balance drilldown"],"fullName":"address filter extraction for balance drilldown derives month period for balance snapshot from 'на 2020.05'","status":"passed","title":"derives month period for balance snapshot from 'на 2020.05'","duration":0.126700000000028,"failureMessages":[],"meta":{}},{"ancestorTitles":["address filter extraction for balance drilldown"],"fullName":"address filter extraction for balance drilldown derives month period for balance snapshot from 'на 2020 май'","status":"passed","title":"derives month period for balance snapshot from 'на 2020 май'","duration":0.11300000000005639,"failureMessages":[],"meta":{}},{"ancestorTitles":["address filter extraction for balance drilldown"],"fullName":"address filter extraction for balance drilldown extracts dotted account by heuristic for docs-forming phrasing without 'счет' keyword","status":"passed","title":"extracts dotted account by heuristic for docs-forming phrasing without 'счет' keyword","duration":0.17639999999994416,"failureMessages":[],"meta":{}},{"ancestorTitles":["address filter extraction for balance drilldown"],"fullName":"address filter extraction for balance drilldown extracts dotted account by heuristic for short balance slang","status":"passed","title":"extracts dotted account by heuristic for short balance slang","duration":0.13059999999995853,"failureMessages":[],"meta":{}},{"ancestorTitles":["address filter extraction for balance drilldown"],"fullName":"address filter extraction for balance drilldown does not derive counterparty from follow-up filler token in bank phrase","status":"passed","title":"does not derive counterparty from follow-up filler token in bank phrase","duration":6.56759999999997,"failureMessages":[],"meta":{}},{"ancestorTitles":["address filter extraction for balance drilldown"],"fullName":"address filter extraction for balance drilldown keeps compact account for docs-forming follow-up and avoids fake counterparty anchor","status":"passed","title":"keeps compact account for docs-forming follow-up and avoids fake counterparty anchor","duration":0.1612999999999829,"failureMessages":[],"meta":{}},{"ancestorTitles":["address filter extraction for balance drilldown"],"fullName":"address filter extraction for balance drilldown drops accidental account for non-account intent without explicit account cue","status":"passed","title":"drops accidental account for non-account intent without explicit account cue","duration":0.7043999999999642,"failureMessages":[],"meta":{}},{"ancestorTitles":["address filter extraction for balance drilldown"],"fullName":"address filter extraction for balance drilldown extracts leading counterparty token for short bank phrase","status":"passed","title":"extracts leading counterparty token for short bank phrase","duration":1.5855000000000246,"failureMessages":[],"meta":{}},{"ancestorTitles":["address filter extraction for balance drilldown"],"fullName":"address filter extraction for balance drilldown treats 'за весь период' as all-time hint and does not force 90-day default","status":"passed","title":"treats 'за весь период' as all-time hint and does not force 90-day default","duration":0.21519999999998163,"failureMessages":[],"meta":{}},{"ancestorTitles":["address filter extraction for balance drilldown"],"fullName":"address filter extraction for balance drilldown extracts loose by-anchor and year period for short slang docs phrase","status":"passed","title":"extracts loose by-anchor and year period for short slang docs phrase","duration":0.16380000000003747,"failureMessages":[],"meta":{}},{"ancestorTitles":["address filter extraction for balance drilldown"],"fullName":"address filter extraction for balance drilldown extracts implicit counterparty and short-year period for typo slang docs phrase","status":"passed","title":"extracts implicit counterparty and short-year period for typo slang docs phrase","duration":0.15560000000004948,"failureMessages":[],"meta":{}},{"ancestorTitles":["address filter extraction for balance drilldown"],"fullName":"address filter extraction for balance drilldown does not use filler token 'есть' as counterparty when explicit shorthand anchor exists","status":"passed","title":"does not use filler token 'есть' as counterparty when explicit shorthand anchor exists","duration":0.2800000000000864,"failureMessages":[],"meta":{}},{"ancestorTitles":["address filter extraction for balance drilldown"],"fullName":"address filter extraction for balance drilldown extracts free-text counterparty and relaxed short-year period from noisy phrase","status":"passed","title":"extracts free-text counterparty and relaxed short-year period from noisy phrase","duration":0.2159000000000333,"failureMessages":[],"meta":{}},{"ancestorTitles":["address filter extraction for balance drilldown"],"fullName":"address filter extraction for balance drilldown extracts short ordinal year period from noisy docs phrase","status":"passed","title":"extracts short ordinal year period from noisy docs phrase","duration":0.1250999999999749,"failureMessages":[],"meta":{}},{"ancestorTitles":["address filter extraction for balance drilldown"],"fullName":"address filter extraction for balance drilldown extracts short bare year period from follow-up phrase","status":"passed","title":"extracts short bare year period from follow-up phrase","duration":0.09940000000005966,"failureMessages":[],"meta":{}},{"ancestorTitles":["address filter extraction for balance drilldown"],"fullName":"address filter extraction for balance drilldown does not use action verb as counterparty when phrase is 'Показать документы '","status":"passed","title":"does not use action verb as counterparty when phrase is 'Показать документы '","duration":0.1429000000000542,"failureMessages":[],"meta":{}},{"ancestorTitles":["address filter extraction for balance drilldown"],"fullName":"address filter extraction for balance drilldown extracts counterparty and short year from transliterated noisy phrase","status":"passed","title":"extracts counterparty and short year from transliterated noisy phrase","duration":1.304300000000012,"failureMessages":[],"meta":{}},{"ancestorTitles":["address filter extraction for balance drilldown"],"fullName":"address filter extraction for balance drilldown does not treat transliterated filler verb as counterparty in docy phrase","status":"passed","title":"does not treat transliterated filler verb as counterparty in docy phrase","duration":1.1014000000000124,"failureMessages":[],"meta":{}},{"ancestorTitles":["address filter extraction for balance drilldown"],"fullName":"address filter extraction for balance drilldown repairs mojibake phrase before extracting counterparty filters","status":"passed","title":"repairs mojibake phrase before extracting counterparty filters","duration":6.95920000000001,"failureMessages":[],"meta":{}},{"ancestorTitles":["address filter extraction for balance drilldown"],"fullName":"address filter extraction for balance drilldown extracts explicit year range period from phrase","status":"passed","title":"extracts explicit year range period from phrase","duration":0.21900000000005093,"failureMessages":[],"meta":{}},{"ancestorTitles":["address filter extraction for balance drilldown"],"fullName":"address filter extraction for balance drilldown extracts contract and year period for contract document list","status":"passed","title":"extracts contract and year period for contract document list","duration":0.547200000000089,"failureMessages":[],"meta":{}},{"ancestorTitles":["address filter extraction for balance drilldown"],"fullName":"address filter extraction for balance drilldown extracts contracts-by-counterparty anchor with numeric suffix from loose 'по ...' phrase","status":"passed","title":"extracts contracts-by-counterparty anchor with numeric suffix from loose 'по ...' phrase","duration":0.21659999999997126,"failureMessages":[],"meta":{}},{"ancestorTitles":["address filter extraction for balance drilldown"],"fullName":"address filter extraction for balance drilldown cuts trailing as-of date from contract anchor","status":"passed","title":"cuts trailing as-of date from contract anchor","duration":0.3795999999999822,"failureMessages":[],"meta":{}},{"ancestorTitles":["address filter extraction for balance drilldown"],"fullName":"address filter extraction for balance drilldown does not force 90-day default window for by-contract query without explicit period","status":"passed","title":"does not force 90-day default window for by-contract query without explicit period","duration":0.33550000000002456,"failureMessages":[],"meta":{}},{"ancestorTitles":["address filter extraction for balance drilldown"],"fullName":"address filter extraction for balance drilldown extracts heuristic contract token for noisy contract phrase","status":"passed","title":"extracts heuristic contract token for noisy contract phrase","duration":0.33619999999996253,"failureMessages":[],"meta":{}},{"ancestorTitles":["address filter extraction for balance drilldown"],"fullName":"address filter extraction for balance drilldown trims english year tail from contract anchor","status":"passed","title":"trims english year tail from contract anchor","duration":0.1374999999999318,"failureMessages":[],"meta":{}},{"ancestorTitles":["address filter extraction for balance drilldown"],"fullName":"address filter extraction for balance drilldown trims trailing separated year from contract anchor","status":"passed","title":"trims trailing separated year from contract anchor","duration":0.0886000000000422,"failureMessages":[],"meta":{}},{"ancestorTitles":["address filter extraction for balance drilldown"],"fullName":"address filter extraction for balance drilldown trims explanatory tail after contract token","status":"passed","title":"trims explanatory tail after contract token","duration":0.08670000000006439,"failureMessages":[],"meta":{}},{"ancestorTitles":["address filter extraction for balance drilldown"],"fullName":"address filter extraction for balance drilldown extracts multiline year range period from phrase","status":"passed","title":"extracts multiline year range period from phrase","duration":0.27890000000002146,"failureMessages":[],"meta":{}},{"ancestorTitles":["address filter extraction for balance drilldown"],"fullName":"address filter extraction for balance drilldown extracts russian year range period from 'с ... по ...' phrase","status":"passed","title":"extracts russian year range period from 'с ... по ...' phrase","duration":0.19299999999998363,"failureMessages":[],"meta":{}},{"ancestorTitles":["address filter extraction for balance drilldown"],"fullName":"address filter extraction for balance drilldown treats 'за любой период' as all-time hint and keeps loose by-anchor","status":"passed","title":"treats 'за любой период' as all-time hint and keeps loose by-anchor","duration":0.16800000000000637,"failureMessages":[],"meta":{}},{"ancestorTitles":["address query limited taxonomy and stage diagnostics"],"fullName":"address query limited taxonomy and stage diagnostics injects as_of_date from analysis context when user message has no explicit period","status":"passed","title":"injects as_of_date from analysis context when user message has no explicit period","duration":3.094400000000064,"failureMessages":[],"meta":{}},{"ancestorTitles":["address query limited taxonomy and stage diagnostics"],"fullName":"address query limited taxonomy and stage diagnostics returns soft out-of-scope reply without technical jargon for unsupported supplier-control wording","status":"passed","title":"returns soft out-of-scope reply without technical jargon for unsupported supplier-control wording","duration":0.9547000000000025,"failureMessages":[],"meta":{}},{"ancestorTitles":["address query limited taxonomy and stage diagnostics"],"fullName":"address query limited taxonomy and stage diagnostics routes supplier tail-risk wording without forcing missing-anchor fallback","status":"passed","title":"routes supplier tail-risk wording without forcing missing-anchor fallback","duration":960.4023000000001,"failureMessages":[],"meta":{}},{"ancestorTitles":["address query limited taxonomy and stage diagnostics"],"fullName":"address query limited taxonomy and stage diagnostics routes shipment-to-payment lag wording into receivables lane without missing-anchor fallback","status":"failed","title":"routes shipment-to-payment lag wording into receivables lane without missing-anchor fallback","duration":5019.4962,"failureMessages":["Error: STACK_TRACE_ERROR\n at task (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:638:27)\n at Object. (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:662:16)\n at Object. (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:458:28)\n at chain (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:369:14)\n at X:\\1C\\NDC_1C\\llm_normalizer\\backend\\tests\\addressQueryRuntimeM23.test.ts:2370:3\n at file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:734:40\n at runWithSuite (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1849:8)\n at Object.collect (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:734:10)\n at Object.collect (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:738:54)\n at processTicksAndRejections (node:internal/process/task_queues:105:5)\n at collectTests (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1179:25)\n at startTests (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1817:17)\n at file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/vitest/dist/chunks/runBaseTests.9Ij9_de-.js:117:26\n at withEnv (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/vitest/dist/chunks/runBaseTests.9Ij9_de-.js:84:3)\n at run (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/vitest/dist/chunks/runBaseTests.9Ij9_de-.js:109:2)"],"meta":{}},{"ancestorTitles":["address query limited taxonomy and stage diagnostics"],"fullName":"address query limited taxonomy and stage diagnostics routes payments-without-closing-docs wording into open contracts lane","status":"failed","title":"routes payments-without-closing-docs wording into open contracts lane","duration":5008.013900000001,"failureMessages":["Error: STACK_TRACE_ERROR\n at task (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:638:27)\n at Object. (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:662:16)\n at Object. (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:458:28)\n at chain (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:369:14)\n at X:\\1C\\NDC_1C\\llm_normalizer\\backend\\tests\\addressQueryRuntimeM23.test.ts:2381:3\n at file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:734:40\n at runWithSuite (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1849:8)\n at Object.collect (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:734:10)\n at Object.collect (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:738:54)\n at processTicksAndRejections (node:internal/process/task_queues:105:5)\n at collectTests (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1179:25)\n at startTests (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1817:17)\n at file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/vitest/dist/chunks/runBaseTests.9Ij9_de-.js:117:26\n at withEnv (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/vitest/dist/chunks/runBaseTests.9Ij9_de-.js:84:3)\n at run (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/vitest/dist/chunks/runBaseTests.9Ij9_de-.js:109:2)"],"meta":{}},{"ancestorTitles":["address query limited taxonomy and stage diagnostics"],"fullName":"address query limited taxonomy and stage diagnostics routes stale advances wording into open contracts lane without missing-anchor fallback","status":"failed","title":"routes stale advances wording into open contracts lane without missing-anchor fallback","duration":5008.172200000001,"failureMessages":["Error: STACK_TRACE_ERROR\n at task (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:638:27)\n at Object. (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:662:16)\n at Object. (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:458:28)\n at chain (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:369:14)\n at X:\\1C\\NDC_1C\\llm_normalizer\\backend\\tests\\addressQueryRuntimeM23.test.ts:2392:3\n at file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:734:40\n at runWithSuite (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1849:8)\n at Object.collect (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:734:10)\n at Object.collect (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:738:54)\n at processTicksAndRejections (node:internal/process/task_queues:105:5)\n at collectTests (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1179:25)\n at startTests (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1817:17)\n at file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/vitest/dist/chunks/runBaseTests.9Ij9_de-.js:117:26\n at withEnv (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/vitest/dist/chunks/runBaseTests.9Ij9_de-.js:84:3)\n at run (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/vitest/dist/chunks/runBaseTests.9Ij9_de-.js:109:2)"],"meta":{}},{"ancestorTitles":["address query limited taxonomy and stage diagnostics"],"fullName":"address query limited taxonomy and stage diagnostics routes non-paying counterparties month-risk wording into receivables lane","status":"failed","title":"routes non-paying counterparties month-risk wording into receivables lane","duration":5014.0358000000015,"failureMessages":["Error: STACK_TRACE_ERROR\n at task (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:638:27)\n at Object. (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:662:16)\n at Object. (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:458:28)\n at chain (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:369:14)\n at X:\\1C\\NDC_1C\\llm_normalizer\\backend\\tests\\addressQueryRuntimeM23.test.ts:2403:3\n at file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:734:40\n at runWithSuite (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1849:8)\n at Object.collect (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:734:10)\n at Object.collect (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:738:54)\n at processTicksAndRejections (node:internal/process/task_queues:105:5)\n at collectTests (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1179:25)\n at startTests (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1817:17)\n at file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/vitest/dist/chunks/runBaseTests.9Ij9_de-.js:117:26\n at withEnv (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/vitest/dist/chunks/runBaseTests.9Ij9_de-.js:84:3)\n at run (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/vitest/dist/chunks/runBaseTests.9Ij9_de-.js:109:2)"],"meta":{}},{"ancestorTitles":["address query limited taxonomy and stage diagnostics"],"fullName":"address query limited taxonomy and stage diagnostics routes documents-without-payments wording into open contracts lane","status":"failed","title":"routes documents-without-payments wording into open contracts lane","duration":5015.104200000002,"failureMessages":["Error: STACK_TRACE_ERROR\n at task (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:638:27)\n at Object. (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:662:16)\n at Object. (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:458:28)\n at chain (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:369:14)\n at X:\\1C\\NDC_1C\\llm_normalizer\\backend\\tests\\addressQueryRuntimeM23.test.ts:2415:3\n at file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:734:40\n at runWithSuite (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1849:8)\n at Object.collect (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:734:10)\n at Object.collect (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:738:54)\n at processTicksAndRejections (node:internal/process/task_queues:105:5)\n at collectTests (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1179:25)\n at startTests (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1817:17)\n at file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/vitest/dist/chunks/runBaseTests.9Ij9_de-.js:117:26\n at withEnv (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/vitest/dist/chunks/runBaseTests.9Ij9_de-.js:84:3)\n at run (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/vitest/dist/chunks/runBaseTests.9Ij9_de-.js:109:2)"],"meta":{}},{"ancestorTitles":["address query limited taxonomy and stage diagnostics"],"fullName":"address query limited taxonomy and stage diagnostics routes period coverage profile question into dedicated aggregate recipe","status":"failed","title":"routes period coverage profile question into dedicated aggregate recipe","duration":5007.750199999999,"failureMessages":["Error: STACK_TRACE_ERROR\n at task (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:638:27)\n at Object. (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:662:16)\n at Object. (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:458:28)\n at chain (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:369:14)\n at X:\\1C\\NDC_1C\\llm_normalizer\\backend\\tests\\addressQueryRuntimeM23.test.ts:2426:3\n at file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:734:40\n at runWithSuite (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1849:8)\n at Object.collect (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:734:10)\n at Object.collect (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:738:54)\n at processTicksAndRejections (node:internal/process/task_queues:105:5)\n at collectTests (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1179:25)\n at startTests (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1817:17)\n at file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/vitest/dist/chunks/runBaseTests.9Ij9_de-.js:117:26\n at withEnv (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/vitest/dist/chunks/runBaseTests.9Ij9_de-.js:84:3)\n at run (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/vitest/dist/chunks/runBaseTests.9Ij9_de-.js:109:2)"],"meta":{}},{"ancestorTitles":["address query limited taxonomy and stage diagnostics"],"fullName":"address query limited taxonomy and stage diagnostics does not rewrite active-month management question into bank-ops counterparty lane","status":"failed","title":"does not rewrite active-month management question into bank-ops counterparty lane","duration":5010.999200000002,"failureMessages":["Error: STACK_TRACE_ERROR\n at task (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:638:27)\n at Object. (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:662:16)\n at Object. (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:458:28)\n at chain (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:369:14)\n at X:\\1C\\NDC_1C\\llm_normalizer\\backend\\tests\\addressQueryRuntimeM23.test.ts:2437:3\n at file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:734:40\n at runWithSuite (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1849:8)\n at Object.collect (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:734:10)\n at Object.collect (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:738:54)\n at processTicksAndRejections (node:internal/process/task_queues:105:5)\n at collectTests (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1179:25)\n at startTests (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1817:17)\n at file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/vitest/dist/chunks/runBaseTests.9Ij9_de-.js:117:26\n at withEnv (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/vitest/dist/chunks/runBaseTests.9Ij9_de-.js:84:3)\n at run (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/vitest/dist/chunks/runBaseTests.9Ij9_de-.js:109:2)"],"meta":{}},{"ancestorTitles":["address query limited taxonomy and stage diagnostics"],"fullName":"address query limited taxonomy and stage diagnostics routes document+section profile question into dedicated aggregate recipe","status":"failed","title":"routes document+section profile question into dedicated aggregate recipe","duration":5011.141799999998,"failureMessages":["Error: STACK_TRACE_ERROR\n at task (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:638:27)\n at Object. (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:662:16)\n at Object. (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:458:28)\n at chain (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:369:14)\n at X:\\1C\\NDC_1C\\llm_normalizer\\backend\\tests\\addressQueryRuntimeM23.test.ts:2447:3\n at file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:734:40\n at runWithSuite (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1849:8)\n at Object.collect (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:734:10)\n at Object.collect (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:738:54)\n at processTicksAndRejections (node:internal/process/task_queues:105:5)\n at collectTests (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1179:25)\n at startTests (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1817:17)\n at file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/vitest/dist/chunks/runBaseTests.9Ij9_de-.js:117:26\n at withEnv (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/vitest/dist/chunks/runBaseTests.9Ij9_de-.js:84:3)\n at run (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/vitest/dist/chunks/runBaseTests.9Ij9_de-.js:109:2)"],"meta":{}},{"ancestorTitles":["address query limited taxonomy and stage diagnostics"],"fullName":"address query limited taxonomy and stage diagnostics routes counterparty population question into dedicated aggregate recipe","status":"failed","title":"routes counterparty population question into dedicated aggregate recipe","duration":5008.8776,"failureMessages":["Error: STACK_TRACE_ERROR\n at task (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:638:27)\n at Object. (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:662:16)\n at Object. (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:458:28)\n at chain (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:369:14)\n at X:\\1C\\NDC_1C\\llm_normalizer\\backend\\tests\\addressQueryRuntimeM23.test.ts:2458:3\n at file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:734:40\n at runWithSuite (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1849:8)\n at Object.collect (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:734:10)\n at Object.collect (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:738:54)\n at processTicksAndRejections (node:internal/process/task_queues:105:5)\n at collectTests (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1179:25)\n at startTests (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1817:17)\n at file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/vitest/dist/chunks/runBaseTests.9Ij9_de-.js:117:26\n at withEnv (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/vitest/dist/chunks/runBaseTests.9Ij9_de-.js:84:3)\n at run (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/vitest/dist/chunks/runBaseTests.9Ij9_de-.js:109:2)"],"meta":{}},{"ancestorTitles":["address query limited taxonomy and stage diagnostics"],"fullName":"address query limited taxonomy and stage diagnostics routes contract usage overview question into dedicated aggregate recipe","status":"failed","title":"routes contract usage overview question into dedicated aggregate recipe","duration":5017.268100000001,"failureMessages":["Error: STACK_TRACE_ERROR\n at task (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:638:27)\n at Object. (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:662:16)\n at Object. (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:458:28)\n at chain (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:369:14)\n at X:\\1C\\NDC_1C\\llm_normalizer\\backend\\tests\\addressQueryRuntimeM23.test.ts:2468:3\n at file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:734:40\n at runWithSuite (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1849:8)\n at Object.collect (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:734:10)\n at Object.collect (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:738:54)\n at processTicksAndRejections (node:internal/process/task_queues:105:5)\n at collectTests (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1179:25)\n at startTests (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1817:17)\n at file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/vitest/dist/chunks/runBaseTests.9Ij9_de-.js:117:26\n at withEnv (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/vitest/dist/chunks/runBaseTests.9Ij9_de-.js:84:3)\n at run (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/vitest/dist/chunks/runBaseTests.9Ij9_de-.js:109:2)"],"meta":{}},{"ancestorTitles":["address query limited taxonomy and stage diagnostics"],"fullName":"address query limited taxonomy and stage diagnostics routes customer value question into dedicated aggregate recipe","status":"failed","title":"routes customer value question into dedicated aggregate recipe","duration":5001.703800000003,"failureMessages":["Error: STACK_TRACE_ERROR\n at task (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:638:27)\n at Object. (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:662:16)\n at Object. (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:458:28)\n at chain (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:369:14)\n at X:\\1C\\NDC_1C\\llm_normalizer\\backend\\tests\\addressQueryRuntimeM23.test.ts:2478:3\n at file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:734:40\n at runWithSuite (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1849:8)\n at Object.collect (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:734:10)\n at Object.collect (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:738:54)\n at processTicksAndRejections (node:internal/process/task_queues:105:5)\n at collectTests (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1179:25)\n at startTests (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1817:17)\n at file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/vitest/dist/chunks/runBaseTests.9Ij9_de-.js:117:26\n at withEnv (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/vitest/dist/chunks/runBaseTests.9Ij9_de-.js:84:3)\n at run (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/vitest/dist/chunks/runBaseTests.9Ij9_de-.js:109:2)"],"meta":{}},{"ancestorTitles":["address query limited taxonomy and stage diagnostics"],"fullName":"address query limited taxonomy and stage diagnostics routes highest inflow slang wording into customer value aggregate recipe","status":"failed","title":"routes highest inflow slang wording into customer value aggregate recipe","duration":5003.028700000003,"failureMessages":["Error: STACK_TRACE_ERROR\n at task (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:638:27)\n at Object. (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:662:16)\n at Object. (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:458:28)\n at chain (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:369:14)\n at X:\\1C\\NDC_1C\\llm_normalizer\\backend\\tests\\addressQueryRuntimeM23.test.ts:2488:3\n at file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:734:40\n at runWithSuite (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1849:8)\n at Object.collect (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:734:10)\n at Object.collect (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:738:54)\n at processTicksAndRejections (node:internal/process/task_queues:105:5)\n at collectTests (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1179:25)\n at startTests (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1817:17)\n at file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/vitest/dist/chunks/runBaseTests.9Ij9_de-.js:117:26\n at withEnv (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/vitest/dist/chunks/runBaseTests.9Ij9_de-.js:84:3)\n at run (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/vitest/dist/chunks/runBaseTests.9Ij9_de-.js:109:2)"],"meta":{}},{"ancestorTitles":["address query limited taxonomy and stage diagnostics"],"fullName":"address query limited taxonomy and stage diagnostics routes typo highest-check wording into customer value aggregate recipe","status":"failed","title":"routes typo highest-check wording into customer value aggregate recipe","duration":5012.634200000008,"failureMessages":["Error: STACK_TRACE_ERROR\n at task (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:638:27)\n at Object. (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:662:16)\n at Object. (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:458:28)\n at chain (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:369:14)\n at X:\\1C\\NDC_1C\\llm_normalizer\\backend\\tests\\addressQueryRuntimeM23.test.ts:2498:3\n at file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:734:40\n at runWithSuite (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1849:8)\n at Object.collect (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:734:10)\n at Object.collect (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:738:54)\n at processTicksAndRejections (node:internal/process/task_queues:105:5)\n at collectTests (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1179:25)\n at startTests (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1817:17)\n at file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/vitest/dist/chunks/runBaseTests.9Ij9_de-.js:117:26\n at withEnv (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/vitest/dist/chunks/runBaseTests.9Ij9_de-.js:84:3)\n at run (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/vitest/dist/chunks/runBaseTests.9Ij9_de-.js:109:2)"],"meta":{}},{"ancestorTitles":["address query limited taxonomy and stage diagnostics"],"fullName":"address query limited taxonomy and stage diagnostics routes top counterparty slang wording into customer value aggregate recipe","status":"failed","title":"routes top counterparty slang wording into customer value aggregate recipe","duration":5011.106,"failureMessages":["Error: STACK_TRACE_ERROR\n at task (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:638:27)\n at Object. (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:662:16)\n at Object. (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:458:28)\n at chain (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:369:14)\n at X:\\1C\\NDC_1C\\llm_normalizer\\backend\\tests\\addressQueryRuntimeM23.test.ts:2508:3\n at file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:734:40\n at runWithSuite (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1849:8)\n at Object.collect (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:734:10)\n at Object.collect (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:738:54)\n at processTicksAndRejections (node:internal/process/task_queues:105:5)\n at collectTests (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1179:25)\n at startTests (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1817:17)\n at file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/vitest/dist/chunks/runBaseTests.9Ij9_de-.js:117:26\n at withEnv (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/vitest/dist/chunks/runBaseTests.9Ij9_de-.js:84:3)\n at run (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/vitest/dist/chunks/runBaseTests.9Ij9_de-.js:109:2)"],"meta":{}},{"ancestorTitles":["address query limited taxonomy and stage diagnostics"],"fullName":"address query limited taxonomy and stage diagnostics routes supplier payout question into dedicated aggregate recipe","status":"failed","title":"routes supplier payout question into dedicated aggregate recipe","duration":5009.163799999995,"failureMessages":["Error: STACK_TRACE_ERROR\n at task (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:638:27)\n at Object. (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:662:16)\n at Object. (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:458:28)\n at chain (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:369:14)\n at X:\\1C\\NDC_1C\\llm_normalizer\\backend\\tests\\addressQueryRuntimeM23.test.ts:2520:3\n at file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:734:40\n at runWithSuite (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1849:8)\n at Object.collect (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:734:10)\n at Object.collect (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:738:54)\n at processTicksAndRejections (node:internal/process/task_queues:105:5)\n at collectTests (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1179:25)\n at startTests (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1817:17)\n at file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/vitest/dist/chunks/runBaseTests.9Ij9_de-.js:117:26\n at withEnv (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/vitest/dist/chunks/runBaseTests.9Ij9_de-.js:84:3)\n at run (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/vitest/dist/chunks/runBaseTests.9Ij9_de-.js:109:2)"],"meta":{}},{"ancestorTitles":["address query limited taxonomy and stage diagnostics"],"fullName":"address query limited taxonomy and stage diagnostics routes contract value question into dedicated aggregate recipe","status":"passed","title":"routes contract value question into dedicated aggregate recipe","duration":3087.0390000000043,"failureMessages":[],"meta":{}},{"ancestorTitles":["address query limited taxonomy and stage diagnostics"],"fullName":"address query limited taxonomy and stage diagnostics routes top contract wording with 'контракт' into contract value aggregate recipe","status":"passed","title":"routes top contract wording with 'контракт' into contract value aggregate recipe","duration":1017.5210999999981,"failureMessages":[],"meta":{}},{"ancestorTitles":["address query limited taxonomy and stage diagnostics"],"fullName":"address query limited taxonomy and stage diagnostics routes revenue-total slang wording into customer value aggregate recipe (no account-missing fallback)","status":"passed","title":"routes revenue-total slang wording into customer value aggregate recipe (no account-missing fallback)","duration":1005.7629000000015,"failureMessages":[],"meta":{}},{"ancestorTitles":["address query limited taxonomy and stage diagnostics"],"fullName":"address query limited taxonomy and stage diagnostics routes overall-turnover wording into customer value aggregate recipe","status":"passed","title":"routes overall-turnover wording into customer value aggregate recipe","duration":1018.3968000000023,"failureMessages":[],"meta":{}},{"ancestorTitles":["address query limited taxonomy and stage diagnostics"],"fullName":"address query limited taxonomy and stage diagnostics routes VAT payment forecast wording into dedicated VAT forecast recipe","status":"passed","title":"routes VAT payment forecast wording into dedicated VAT forecast recipe","duration":1023.620299999995,"failureMessages":[],"meta":{}},{"ancestorTitles":["address query limited taxonomy and stage diagnostics"],"fullName":"address query limited taxonomy and stage diagnostics routes colloquial VAT payable estimate wording into VAT forecast recipe","status":"passed","title":"routes colloquial VAT payable estimate wording into VAT forecast recipe","duration":1011.3776999999973,"failureMessages":[],"meta":{}},{"ancestorTitles":["address query limited taxonomy and stage diagnostics"],"fullName":"address query limited taxonomy and stage diagnostics routes customer lifecycle question into dedicated aggregate recipe","status":"passed","title":"routes customer lifecycle question into dedicated aggregate recipe","duration":1061.5473000000056,"failureMessages":[],"meta":{}},{"ancestorTitles":["address query limited taxonomy and stage diagnostics"],"fullName":"address query limited taxonomy and stage diagnostics routes roster-style customer wording into lifecycle aggregate recipe","status":"passed","title":"routes roster-style customer wording into lifecycle aggregate recipe","duration":995.5893999999971,"failureMessages":[],"meta":{}},{"ancestorTitles":["address query limited taxonomy and stage diagnostics"],"fullName":"address query limited taxonomy and stage diagnostics routes one-time counterparties wording into lifecycle aggregate recipe","status":"passed","title":"routes one-time counterparties wording into lifecycle aggregate recipe","duration":1006.6540999999997,"failureMessages":[],"meta":{}},{"ancestorTitles":["address query limited taxonomy and stage diagnostics"],"fullName":"address query limited taxonomy and stage diagnostics routes stale contracts wording into contract usage overview recipe","status":"passed","title":"routes stale contracts wording into contract usage overview recipe","duration":964.4989999999962,"failureMessages":[],"meta":{}},{"ancestorTitles":["address query limited taxonomy and stage diagnostics"],"fullName":"address query limited taxonomy and stage diagnostics routes multi-contract counterparties wording into contract usage and value recipe","status":"passed","title":"routes multi-contract counterparties wording into contract usage and value recipe","duration":1056.4967000000033,"failureMessages":[],"meta":{}},{"ancestorTitles":["address query limited taxonomy and stage diagnostics"],"fullName":"address query limited taxonomy and stage diagnostics returns missing_anchor for open items without concrete counterparty/contract anchor","status":"passed","title":"returns missing_anchor for open items without concrete counterparty/contract anchor","duration":1.53870000000461,"failureMessages":[],"meta":{}},{"ancestorTitles":["address query limited taxonomy and stage diagnostics"],"fullName":"address query limited taxonomy and stage diagnostics does not return fallback factual rows for unmatched open-items contract anchor","status":"passed","title":"does not return fallback factual rows for unmatched open-items contract anchor","duration":2338.630799999999,"failureMessages":[],"meta":{}},{"ancestorTitles":["address query limited taxonomy and stage diagnostics"],"fullName":"address query limited taxonomy and stage diagnostics does not return broad fallback document list when counterparty anchor is not matched","status":"passed","title":"does not return broad fallback document list when counterparty anchor is not matched","duration":3978.724199999997,"failureMessages":[],"meta":{}},{"ancestorTitles":["address query limited taxonomy and stage diagnostics"],"fullName":"address query limited taxonomy and stage diagnostics does not keep report-date phrase inside open-items counterparty anchor","status":"passed","title":"does not keep report-date phrase inside open-items counterparty anchor","duration":858.4956000000093,"failureMessages":[],"meta":{}},{"ancestorTitles":["address query limited taxonomy and stage diagnostics"],"fullName":"address query limited taxonomy and stage diagnostics routes contract document list intent into address recipe","status":"passed","title":"routes contract document list intent into address recipe","duration":1149.6627000000008,"failureMessages":[],"meta":{}},{"ancestorTitles":["address query limited taxonomy and stage diagnostics"],"fullName":"address query limited taxonomy and stage diagnostics routes contracts-by-counterparty intent into dedicated catalog recipe","status":"passed","title":"routes contracts-by-counterparty intent into dedicated catalog recipe","duration":876.3346999999922,"failureMessages":[],"meta":{}},{"ancestorTitles":["address query limited taxonomy and stage diagnostics"],"fullName":"address query limited taxonomy and stage diagnostics routes bank operations by contract intent into address recipe","status":"passed","title":"routes bank operations by contract intent into address recipe","duration":1176.017399999997,"failureMessages":[],"meta":{}},{"ancestorTitles":["address query limited taxonomy and stage diagnostics"],"fullName":"address query limited taxonomy and stage diagnostics includes resolver and row-stage diagnostics","status":"passed","title":"includes resolver and row-stage diagnostics","duration":792.957699999999,"failureMessages":[],"meta":{}},{"ancestorTitles":["address query limited taxonomy and stage diagnostics"],"fullName":"address query limited taxonomy and stage diagnostics keeps short slang docs request in address lane (no deep fallback)","status":"passed","title":"keeps short slang docs request in address lane (no deep fallback)","duration":1026.6021000000037,"failureMessages":[],"meta":{}},{"ancestorTitles":["address query limited taxonomy and stage diagnostics"],"fullName":"address query limited taxonomy and stage diagnostics keeps typo slang docs request in address lane and extracts implicit anchor","status":"passed","title":"keeps typo slang docs request in address lane and extracts implicit anchor","duration":1005.8530000000028,"failureMessages":[],"meta":{}},{"ancestorTitles":["address query limited taxonomy and stage diagnostics"],"fullName":"address query limited taxonomy and stage diagnostics keeps noisy docs request in address lane and ignores slang tail token","status":"passed","title":"keeps noisy docs request in address lane and ignores slang tail token","duration":1010.7235000000073,"failureMessages":[],"meta":{}},{"ancestorTitles":["address query limited taxonomy and stage diagnostics"],"fullName":"address query limited taxonomy and stage diagnostics auto-broadens out-of-window period and returns available factual rows","status":"passed","title":"auto-broadens out-of-window period and returns available factual rows","duration":2288.273299999986,"failureMessages":[],"meta":{}},{"ancestorTitles":["address decompose stage follow-up carryover"],"fullName":"address decompose stage follow-up carryover keeps slang all-customers-all-time wording in address lane via resolved intent fallback","status":"passed","title":"keeps slang all-customers-all-time wording in address lane via resolved intent fallback","duration":0.6160000000090804,"failureMessages":[],"meta":{}},{"ancestorTitles":["address decompose stage follow-up carryover"],"fullName":"address decompose stage follow-up carryover keeps churn wording with year in address lane via resolved intent fallback","status":"passed","title":"keeps churn wording with year in address lane via resolved intent fallback","duration":0.2915000000066357,"failureMessages":[],"meta":{}},{"ancestorTitles":["address decompose stage follow-up carryover"],"fullName":"address decompose stage follow-up carryover uses short bare year in follow-up period switch","status":"passed","title":"uses short bare year in follow-up period switch","duration":2.422100000010687,"failureMessages":[],"meta":{}},{"ancestorTitles":["address decompose stage follow-up carryover"],"fullName":"address decompose stage follow-up carryover keeps lifecycle follow-up phrasing with referential pointer and inherits period","status":"passed","title":"keeps lifecycle follow-up phrasing with referential pointer and inherits period","duration":0.8997999999992317,"failureMessages":[],"meta":{}},{"ancestorTitles":["address decompose stage follow-up carryover"],"fullName":"address decompose stage follow-up carryover keeps short period follow-up in address lane and preserves previous counterparty anchor","status":"passed","title":"keeps short period follow-up in address lane and preserves previous counterparty anchor","duration":1.5663000000058673,"failureMessages":[],"meta":{}},{"ancestorTitles":["address decompose stage follow-up carryover"],"fullName":"address decompose stage follow-up carryover inherits organization scope from follow-up context when organization is omitted in user text","status":"passed","title":"inherits organization scope from follow-up context when organization is omitted in user text","duration":0.6869000000006054,"failureMessages":[],"meta":{}},{"ancestorTitles":["address decompose stage follow-up carryover"],"fullName":"address decompose stage follow-up carryover inherits as_of_date from previous period for same-date balance follow-up","status":"passed","title":"inherits as_of_date from previous period for same-date balance follow-up","duration":0.3729999999923166,"failureMessages":[],"meta":{}},{"ancestorTitles":["address decompose stage follow-up carryover"],"fullName":"address decompose stage follow-up carryover keeps contract scope when follow-up asks for bank operations without explicit anchor","status":"passed","title":"keeps contract scope when follow-up asks for bank operations without explicit anchor","duration":1.0345000000088476,"failureMessages":[],"meta":{}},{"ancestorTitles":["address decompose stage follow-up carryover"],"fullName":"address decompose stage follow-up carryover replaces noisy follow-up contract anchor with previous contract from context","status":"passed","title":"replaces noisy follow-up contract anchor with previous contract from context","duration":0.6679000000003725,"failureMessages":[],"meta":{}},{"ancestorTitles":["address decompose stage follow-up carryover"],"fullName":"address decompose stage follow-up carryover replaces noisy referential counterparty anchor with previous counterparty from context","status":"passed","title":"replaces noisy referential counterparty anchor with previous counterparty from context","duration":0.43540000000211876,"failureMessages":[],"meta":{}},{"ancestorTitles":["address decompose stage follow-up carryover"],"fullName":"address decompose stage follow-up carryover replaces 'кроме этого документа...' pseudo-anchor with previous counterparty from follow-up context","status":"passed","title":"replaces 'кроме этого документа...' pseudo-anchor with previous counterparty from follow-up context","duration":0.5041000000055647,"failureMessages":[],"meta":{}},{"ancestorTitles":["address decompose stage follow-up carryover"],"fullName":"address decompose stage follow-up carryover promotes open-items intent from follow-up wording with inherited contract anchor","status":"passed","title":"promotes open-items intent from follow-up wording with inherited contract anchor","duration":0.7113000000099419,"failureMessages":[],"meta":{}},{"ancestorTitles":["address decompose stage follow-up carryover"],"fullName":"address decompose stage follow-up carryover keeps balance family in follow-up when user gives compact account token","status":"passed","title":"keeps balance family in follow-up when user gives compact account token","duration":1.0345000000088476,"failureMessages":[],"meta":{}},{"ancestorTitles":["address decompose stage follow-up carryover"],"fullName":"address decompose stage follow-up carryover does not downgrade inherited follow-up anchor to missing_anchor when period has no rows","status":"passed","title":"does not downgrade inherited follow-up anchor to missing_anchor when period has no rows","duration":4070.907400000011,"failureMessages":[],"meta":{}},{"ancestorTitles":["address decompose stage follow-up carryover"],"fullName":"address decompose stage follow-up carryover keeps VAT explain follow-up in address lane and inherits previous period window","status":"passed","title":"keeps VAT explain follow-up in address lane and inherits previous period window","duration":0.5942000000068219,"failureMessages":[],"meta":{}},{"ancestorTitles":["address recipe catalog counterparty filtering"],"fullName":"address recipe catalog counterparty filtering selects period coverage profile recipe and keeps aggregate markers","status":"passed","title":"selects period coverage profile recipe and keeps aggregate markers","duration":0.18009999999776483,"failureMessages":[],"meta":{}},{"ancestorTitles":["address recipe catalog counterparty filtering"],"fullName":"address recipe catalog counterparty filtering selects document+section profile recipe and keeps aggregate markers","status":"passed","title":"selects document+section profile recipe and keeps aggregate markers","duration":0.1220000000030268,"failureMessages":[],"meta":{}},{"ancestorTitles":["address recipe catalog counterparty filtering"],"fullName":"address recipe catalog counterparty filtering selects counterparty population recipe and keeps aggregate markers","status":"passed","title":"selects counterparty population recipe and keeps aggregate markers","duration":0.0819000000046799,"failureMessages":[],"meta":{}},{"ancestorTitles":["address recipe catalog counterparty filtering"],"fullName":"address recipe catalog counterparty filtering selects contract usage overview recipe and keeps aggregate markers","status":"passed","title":"selects contract usage overview recipe and keeps aggregate markers","duration":0.06429999999818392,"failureMessages":[],"meta":{}},{"ancestorTitles":["address recipe catalog counterparty filtering"],"fullName":"address recipe catalog counterparty filtering selects customer value recipe and keeps top-20 default","status":"passed","title":"selects customer value recipe and keeps top-20 default","duration":0.06109999999171123,"failureMessages":[],"meta":{}},{"ancestorTitles":["address recipe catalog counterparty filtering"],"fullName":"address recipe catalog counterparty filtering selects supplier payouts recipe and keeps top-20 default","status":"passed","title":"selects supplier payouts recipe and keeps top-20 default","duration":0.05719999999564607,"failureMessages":[],"meta":{}},{"ancestorTitles":["address recipe catalog counterparty filtering"],"fullName":"address recipe catalog counterparty filtering selects contract value recipe and keeps top-20 default","status":"passed","title":"selects contract value recipe and keeps top-20 default","duration":0.06560000000172295,"failureMessages":[],"meta":{}},{"ancestorTitles":["address recipe catalog counterparty filtering"],"fullName":"address recipe catalog counterparty filtering selects contracts-by-counterparty recipe from contract catalog","status":"passed","title":"selects contracts-by-counterparty recipe from contract catalog","duration":0.08049999999639113,"failureMessages":[],"meta":{}},{"ancestorTitles":["address recipe catalog counterparty filtering"],"fullName":"address recipe catalog counterparty filtering selects counterparty lifecycle recipe and keeps activity marker","status":"passed","title":"selects counterparty lifecycle recipe and keeps activity marker","duration":0.05139999999664724,"failureMessages":[],"meta":{}},{"ancestorTitles":["address recipe catalog counterparty filtering"],"fullName":"address recipe catalog counterparty filtering boosts limit for all-time counterparty queries","status":"passed","title":"boosts limit for all-time counterparty queries","duration":0.09850000000733417,"failureMessages":[],"meta":{}},{"ancestorTitles":["address recipe catalog counterparty filtering"],"fullName":"address recipe catalog counterparty filtering supports ascending order plan for historical counterparty lookup","status":"passed","title":"supports ascending order plan for historical counterparty lookup","duration":0.05860000000393484,"failureMessages":[],"meta":{}},{"ancestorTitles":["address recipe catalog counterparty filtering"],"fullName":"address recipe catalog counterparty filtering boosts limit for english all-time counterparty queries","status":"passed","title":"boosts limit for english all-time counterparty queries","duration":0.08050000001094304,"failureMessages":[],"meta":{}},{"ancestorTitles":["address recipe catalog counterparty filtering"],"fullName":"address recipe catalog counterparty filtering cuts english all-time tail from counterparty anchor","status":"passed","title":"cuts english all-time tail from counterparty anchor","duration":0.1006000000052154,"failureMessages":[],"meta":{}},{"ancestorTitles":["address recipe catalog counterparty filtering"],"fullName":"address recipe catalog counterparty filtering boosts limit for account snapshot queries with explicit account","status":"passed","title":"boosts limit for account snapshot queries with explicit account","duration":0.08320000000821892,"failureMessages":[],"meta":{}},{"ancestorTitles":["address recipe catalog counterparty filtering"],"fullName":"address recipe catalog counterparty filtering allows extended limit for open-items by contract intent","status":"passed","title":"allows extended limit for open-items by contract intent","duration":0.04879999998956919,"failureMessages":[],"meta":{}},{"ancestorTitles":["address recipe catalog counterparty filtering"],"fullName":"address recipe catalog counterparty filtering uses bank-doc profile with contract projection for open-items anchor matching","status":"passed","title":"uses bank-doc profile with contract projection for open-items anchor matching","duration":0.07359999998880085,"failureMessages":[],"meta":{}},{"ancestorTitles":["address recipe catalog counterparty filtering"],"fullName":"address recipe catalog counterparty filtering allows extended limit for open-contracts intent","status":"passed","title":"allows extended limit for open-contracts intent","duration":0.043699999994714744,"failureMessages":[],"meta":{}},{"ancestorTitles":["address recipe catalog counterparty filtering"],"fullName":"address recipe catalog counterparty filtering injects account condition into movements query for account snapshot","status":"passed","title":"injects account condition into movements query for account snapshot","duration":0.07019999998738058,"failureMessages":[],"meta":{}},{"ancestorTitles":["address recipe catalog counterparty filtering"],"fullName":"address recipe catalog counterparty filtering injects subaccount condition variants into movements query for documents_forming_balance","status":"passed","title":"injects subaccount condition variants into movements query for documents_forming_balance","duration":0.06560000000172295,"failureMessages":[],"meta":{}},{"ancestorTitles":["address recipe catalog counterparty filtering"],"fullName":"address recipe catalog counterparty filtering builds VAT forecast query with safe account-prefix checks instead of presentation-like clauses","status":"passed","title":"builds VAT forecast query with safe account-prefix checks instead of presentation-like clauses","duration":0.27079999999841675,"failureMessages":[],"meta":{}}],"startTime":1775902594077,"endTime":1775902704131.2708,"status":"failed","message":"","name":"X:/1C/NDC_1C/llm_normalizer/backend/tests/addressQueryRuntimeM23.test.ts"},{"assertionResults":[{"ancestorTitles":["assistant address attempt runtime adapter"],"fullName":"assistant address attempt runtime adapter wires lane, response and living-chat attempt runtimes through one boundary","status":"passed","title":"wires lane, response and living-chat attempt runtimes through one boundary","duration":4.087799999999987,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant address attempt runtime adapter"],"fullName":"assistant address attempt runtime adapter passes empty payload fields to address runtime without breaking defaults","status":"passed","title":"passes empty payload fields to address runtime without breaking defaults","duration":0.4031999999999982,"failureMessages":[],"meta":{}}],"startTime":1775902595476,"endTime":1775902595480.4033,"status":"passed","message":"","name":"X:/1C/NDC_1C/llm_normalizer/backend/tests/assistantAddressAttemptRuntimeAdapter.test.ts"},{"assertionResults":[{"ancestorTitles":["assistant address follow-up carryover"],"fullName":"assistant address follow-up carryover keeps short follow-up in address lane by reusing previous anchor context","status":"passed","title":"keeps short follow-up in address lane by reusing previous anchor context","duration":63.01340000000005,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant address follow-up carryover"],"fullName":"assistant address follow-up carryover treats short 'по также' phrase as follow-up for address lane","status":"passed","title":"treats short 'по также' phrase as follow-up for address lane","duration":6.771299999999883,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant address follow-up carryover"],"fullName":"assistant address follow-up carryover treats short affirmative 'давай' as follow-up for previous address answer","status":"passed","title":"treats short affirmative 'давай' as follow-up for previous address answer","duration":6.203199999999924,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant address follow-up carryover"],"fullName":"assistant address follow-up carryover treats typo imperative 'показывыай' as implicit continuation and switches to suggested follow-up intent","status":"passed","title":"treats typo imperative 'показывыай' as implicit continuation and switches to suggested follow-up intent","duration":2.3453000000001794,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant address follow-up carryover"],"fullName":"assistant address follow-up carryover keeps previous counterparty context for referential follow-up 'кроме этого документа...'","status":"passed","title":"keeps previous counterparty context for referential follow-up 'кроме этого документа...'","duration":4.698599999999942,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant address follow-up carryover"],"fullName":"assistant address follow-up carryover retries with raw user message after rewrite degraded anchor and returns factual follow-up result","status":"passed","title":"retries with raw user message after rewrite degraded anchor and returns factual follow-up result","duration":2.9907000000000608,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant address follow-up carryover"],"fullName":"assistant address follow-up carryover reuses last real address context after intermediate clarification fallback","status":"passed","title":"reuses last real address context after intermediate clarification fallback","duration":48.2505000000001,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant address follow-up carryover"],"fullName":"assistant address follow-up carryover does not carry address follow-up context into capability question","status":"passed","title":"does not carry address follow-up context into capability question","duration":6.714999999999918,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant address follow-up carryover"],"fullName":"assistant address follow-up carryover passes active organization scope into address lane follow-up context","status":"passed","title":"passes active organization scope into address lane follow-up context","duration":8.339899999999943,"failureMessages":[],"meta":{}}],"startTime":1775902594527,"endTime":1775902594677.3398,"status":"passed","message":"","name":"X:/1C/NDC_1C/llm_normalizer/backend/tests/assistantAddressFollowupContext.test.ts"},{"assertionResults":[{"ancestorTitles":["assistant address lane attempt input builder"],"fullName":"assistant address lane attempt input builder builds lane-attempt runtime input with message, carry meta and analysis date","status":"passed","title":"builds lane-attempt runtime input with message, carry meta and analysis date","duration":1.4598000000000013,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant address lane attempt input builder"],"fullName":"assistant address lane attempt input builder preserves injected callbacks and nullable fields","status":"passed","title":"preserves injected callbacks and nullable fields","duration":0.9743999999999744,"failureMessages":[],"meta":{}}],"startTime":1775902595961,"endTime":1775902595963.9744,"status":"passed","message":"","name":"X:/1C/NDC_1C/llm_normalizer/backend/tests/assistantAddressLaneAttemptInputBuilder.test.ts"},{"assertionResults":[{"ancestorTitles":["assistant address lane attempt query options builder"],"fullName":"assistant address lane attempt query options builder extracts followup context object from carry meta","status":"passed","title":"extracts followup context object from carry meta","duration":0.9594999999999914,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant address lane attempt query options builder"],"fullName":"assistant address lane attempt query options builder builds query options with scoped followup context when present","status":"passed","title":"builds query options with scoped followup context when present","duration":0.19409999999999172,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant address lane attempt query options builder"],"fullName":"assistant address lane attempt query options builder builds query options with only analysis date when scoped context is missing","status":"passed","title":"builds query options with only analysis date when scoped context is missing","duration":0.09499999999999886,"failureMessages":[],"meta":{}}],"startTime":1775902596193,"endTime":1775902596194.194,"status":"passed","message":"","name":"X:/1C/NDC_1C/llm_normalizer/backend/tests/assistantAddressLaneAttemptQueryOptionsBuilder.test.ts"},{"assertionResults":[{"ancestorTitles":["assistant address lane attempt runtime adapter"],"fullName":"assistant address lane attempt runtime adapter uses scoped followup context when available","status":"passed","title":"uses scoped followup context when available","duration":2.289500000000004,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant address lane attempt runtime adapter"],"fullName":"assistant address lane attempt runtime adapter falls back to plain attempt when scoped followup context is empty","status":"passed","title":"falls back to plain attempt when scoped followup context is empty","duration":0.30400000000000205,"failureMessages":[],"meta":{}}],"startTime":1775902595873,"endTime":1775902595875.304,"status":"passed","message":"","name":"X:/1C/NDC_1C/llm_normalizer/backend/tests/assistantAddressLaneAttemptRuntimeAdapter.test.ts"},{"assertionResults":[{"ancestorTitles":["assistant address lane response attempt input builder"],"fullName":"assistant address lane response attempt input builder normalizes optional carryover and predecompose meta to null","status":"passed","title":"normalizes optional carryover and predecompose meta to null","duration":1.6976999999999975,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant address lane response attempt input builder"],"fullName":"assistant address lane response attempt input builder preserves explicit metadata and callback wiring","status":"passed","title":"preserves explicit metadata and callback wiring","duration":1.0964999999999918,"failureMessages":[],"meta":{}}],"startTime":1775902595884,"endTime":1775902595886.0964,"status":"passed","message":"","name":"X:/1C/NDC_1C/llm_normalizer/backend/tests/assistantAddressLaneResponseAttemptInputBuilder.test.ts"},{"assertionResults":[{"ancestorTitles":["assistant address lane response attempt runtime adapter"],"fullName":"assistant address lane response attempt runtime adapter returns delegated runtime response","status":"passed","title":"returns delegated runtime response","duration":3.295099999999991,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant address lane response attempt runtime adapter"],"fullName":"assistant address lane response attempt runtime adapter forwards carryover and llm predecompose metadata","status":"passed","title":"forwards carryover and llm predecompose metadata","duration":0.5002000000000066,"failureMessages":[],"meta":{}}],"startTime":1775902595584,"endTime":1775902595587.5002,"status":"passed","message":"","name":"X:/1C/NDC_1C/llm_normalizer/backend/tests/assistantAddressLaneResponseAttemptRuntimeAdapter.test.ts"},{"assertionResults":[{"ancestorTitles":["assistant address lane response runtime adapter"],"fullName":"assistant address lane response runtime adapter builds debug payload and finalizes address turn","status":"passed","title":"builds debug payload and finalizes address turn","duration":2.8543999999999983,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant address lane response runtime adapter"],"fullName":"assistant address lane response runtime adapter keeps debug minimal when optional enrichment is absent","status":"passed","title":"keeps debug minimal when optional enrichment is absent","duration":0.29309999999998126,"failureMessages":[],"meta":{}}],"startTime":1775902595538,"endTime":1775902595541.2932,"status":"passed","message":"","name":"X:/1C/NDC_1C/llm_normalizer/backend/tests/assistantAddressLaneResponseRuntimeAdapter.test.ts"},{"assertionResults":[{"ancestorTitles":["assistant address lane response runtime input builder"],"fullName":"assistant address lane response runtime input builder maps lane-response fields into runtime input","status":"passed","title":"maps lane-response fields into runtime input","duration":1.920599999999979,"failureMessages":[],"meta":{}}],"startTime":1775902596272,"endTime":1775902596273.9207,"status":"passed","message":"","name":"X:/1C/NDC_1C/llm_normalizer/backend/tests/assistantAddressLaneResponseRuntimeInputBuilder.test.ts"},{"assertionResults":[{"ancestorTitles":["assistant address lane runtime adapter"],"fullName":"assistant address lane runtime adapter returns contextual lane immediately when preferred contextual attempt is factual","status":"passed","title":"returns contextual lane immediately when preferred contextual attempt is factual","duration":2.116899999999987,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant address lane runtime adapter"],"fullName":"assistant address lane runtime adapter retries with raw message after limited result and returns factual retry","status":"passed","title":"retries with raw message after limited result and returns factual retry","duration":0.3914999999999793,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant address lane runtime adapter"],"fullName":"assistant address lane runtime adapter returns pending limited result when retry is disabled","status":"passed","title":"returns pending limited result when retry is disabled","duration":0.18770000000000664,"failureMessages":[],"meta":{}}],"startTime":1775902595852,"endTime":1775902595855.1877,"status":"passed","message":"","name":"X:/1C/NDC_1C/llm_normalizer/backend/tests/assistantAddressLaneRuntimeAdapter.test.ts"},{"assertionResults":[{"ancestorTitles":["assistant address llm pre-decompose candidate preference"],"fullName":"assistant address llm pre-decompose candidate preference prefers raw fragment when normalized fragment loses counterparty anchor","status":"passed","title":"prefers raw fragment when normalized fragment loses counterparty anchor","duration":54.05060000000003,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant address llm pre-decompose candidate preference"],"fullName":"assistant address llm pre-decompose candidate preference keeps counterparty anchor for docy typo when llm fragment drops anchor","status":"passed","title":"keeps counterparty anchor for docy typo when llm fragment drops anchor","duration":11.200199999999995,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant address llm pre-decompose candidate preference"],"fullName":"assistant address llm pre-decompose candidate preference does not treat service verb as counterparty anchor when llm rewrites noisy bank phrase","status":"passed","title":"does not treat service verb as counterparty anchor when llm rewrites noisy bank phrase","duration":11.712300000000141,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant address llm pre-decompose candidate preference"],"fullName":"assistant address llm pre-decompose candidate preference rejects llm fragment when counterparty anchor is substituted by unrelated noun","status":"passed","title":"rejects llm fragment when counterparty anchor is substituted by unrelated noun","duration":3.534599999999955,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant address llm pre-decompose candidate preference"],"fullName":"assistant address llm pre-decompose candidate preference rejects follow-up intent injection when llm adds documents to same-date account prompt","status":"failed","title":"rejects follow-up intent injection when llm adds documents to same-date account prompt","duration":715.6554000000001,"failureMessages":["AssertionError: expected [] to have a length of 1 but got +0\n at Proxy. (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/expect/dist/index.js:1257:20)\n at Proxy. (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/expect/dist/index.js:1029:14)\n at Proxy.methodWrapper (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/chai/index.js:1686:25)\n at X:\\1C\\NDC_1C\\llm_normalizer\\backend\\tests\\assistantAddressLlmPredecompose.test.ts:534:19\n at processTicksAndRejections (node:internal/process/task_queues:105:5)\n at file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:752:20"],"meta":{}},{"ancestorTitles":["assistant address llm pre-decompose candidate preference"],"fullName":"assistant address llm pre-decompose candidate preference applies deterministic fallback rule when llm fragment is unusable","status":"passed","title":"applies deterministic fallback rule when llm fragment is unusable","duration":2.116800000000012,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant address llm pre-decompose candidate preference"],"fullName":"assistant address llm pre-decompose candidate preference keeps contract anchor in deterministic fallback when llm output is unusable","status":"passed","title":"keeps contract anchor in deterministic fallback when llm output is unusable","duration":3.0159000000001015,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant address llm pre-decompose candidate preference"],"fullName":"assistant address llm pre-decompose candidate preference keeps bank-by-contract intent in deterministic fallback when llm output is unusable","status":"passed","title":"keeps bank-by-contract intent in deterministic fallback when llm output is unusable","duration":1.7355999999999767,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant address llm pre-decompose candidate preference"],"fullName":"assistant address llm pre-decompose candidate preference keeps month scope for balance fallback in 'year month' phrasing","status":"passed","title":"keeps month scope for balance fallback in 'year month' phrasing","duration":2.057399999999916,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant address llm pre-decompose candidate preference"],"fullName":"assistant address llm pre-decompose candidate preference does not pick service words as counterparty anchor in noisy docs query","status":"passed","title":"does not pick service words as counterparty anchor in noisy docs query","duration":2.1756000000000313,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant address llm pre-decompose candidate preference"],"fullName":"assistant address llm pre-decompose candidate preference rewrites payment-style counterparty phrasing to bank operations","status":"passed","title":"rewrites payment-style counterparty phrasing to bank operations","duration":1.5648000000001048,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant address llm pre-decompose candidate preference"],"fullName":"assistant address llm pre-decompose candidate preference rewrites shorthand bank/contract slang phrase to bank operations by contract","status":"passed","title":"rewrites shorthand bank/contract slang phrase to bank operations by contract","duration":1.0465999999998985,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant address llm pre-decompose candidate preference"],"fullName":"assistant address llm pre-decompose candidate preference keeps loose all-time colloquial lookup in address lane without forcing rewrite","status":"failed","title":"keeps loose all-time colloquial lookup in address lane without forcing rewrite","duration":9.990099999999984,"failureMessages":["AssertionError: expected 'clarification_required' to be 'factual' // Object.is equality\n at X:\\1C\\NDC_1C\\llm_normalizer\\backend\\tests\\assistantAddressLlmPredecompose.test.ts:982:33\n at processTicksAndRejections (node:internal/process/task_queues:105:5)\n at file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:752:20"],"meta":{}},{"ancestorTitles":["assistant address llm pre-decompose candidate preference"],"fullName":"assistant address llm pre-decompose candidate preference uses llm canonical candidate as gate signal when regex path has no address markers","status":"failed","title":"uses llm canonical candidate as gate signal when regex path has no address markers","duration":553.1720999999998,"failureMessages":["AssertionError: expected 'clarification_required' to be 'factual' // Object.is equality\n at X:\\1C\\NDC_1C\\llm_normalizer\\backend\\tests\\assistantAddressLlmPredecompose.test.ts:1050:33\n at processTicksAndRejections (node:internal/process/task_queues:105:5)\n at file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:752:20"],"meta":{}},{"ancestorTitles":["assistant address llm pre-decompose candidate preference"],"fullName":"assistant address llm pre-decompose candidate preference normalizes short ordinal year like '20й' in noisy docs phrasing","status":"passed","title":"normalizes short ordinal year like '20й' in noisy docs phrasing","duration":1.625,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant address llm pre-decompose candidate preference"],"fullName":"assistant address llm pre-decompose candidate preference does not treat date fragments as account in balance fallback","status":"passed","title":"does not treat date fragments as account in balance fallback","duration":1.7955999999999221,"failureMessages":[],"meta":{}}],"startTime":1775902594530,"endTime":1775902595906.7957,"status":"failed","message":"","name":"X:/1C/NDC_1C/llm_normalizer/backend/tests/assistantAddressLlmPredecompose.test.ts"},{"assertionResults":[{"ancestorTitles":["assistant address orchestration runtime adapter"],"fullName":"assistant address orchestration runtime adapter uses llm predecompose payload when feature is enabled","status":"passed","title":"uses llm predecompose payload when feature is enabled","duration":1.8171000000000106,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant address orchestration runtime adapter"],"fullName":"assistant address orchestration runtime adapter builds deterministic fallback predecompose payload when feature is disabled","status":"passed","title":"builds deterministic fallback predecompose payload when feature is disabled","duration":0.7352000000000203,"failureMessages":[],"meta":{}}],"startTime":1775902596015,"endTime":1775902596017.735,"status":"passed","message":"","name":"X:/1C/NDC_1C/llm_normalizer/backend/tests/assistantAddressOrchestrationRuntimeAdapter.test.ts"},{"assertionResults":[{"ancestorTitles":["assistant address runtime adapter"],"fullName":"assistant address runtime adapter returns unhandled when address feature is disabled","status":"passed","title":"returns unhandled when address feature is disabled","duration":1.1005999999999858,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant address runtime adapter"],"fullName":"assistant address runtime adapter returns early when tool-gate chat fallback handles","status":"passed","title":"returns early when tool-gate chat fallback handles","duration":1.0193999999999903,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant address runtime adapter"],"fullName":"assistant address runtime adapter finalizes address lane when lane runtime resolves handled selection","status":"passed","title":"finalizes address lane when lane runtime resolves handled selection","duration":1.813699999999983,"failureMessages":[],"meta":{}}],"startTime":1775902595474,"endTime":1775902595478.8137,"status":"passed","message":"","name":"X:/1C/NDC_1C/llm_normalizer/backend/tests/assistantAddressRuntimeAdapter.test.ts"},{"assertionResults":[{"ancestorTitles":["assistant address runtime input builder"],"fullName":"assistant address runtime input builder maps payload provider/useMock/period hint into address runtime input","status":"passed","title":"maps payload provider/useMock/period hint into address runtime input","duration":2.3525999999999954,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant address runtime input builder"],"fullName":"assistant address runtime input builder keeps empty payload fields safe and preserves runtime callbacks","status":"passed","title":"keeps empty payload fields safe and preserves runtime callbacks","duration":0.5793000000000177,"failureMessages":[],"meta":{}}],"startTime":1775902596117,"endTime":1775902596119.5793,"status":"passed","message":"","name":"X:/1C/NDC_1C/llm_normalizer/backend/tests/assistantAddressRuntimeInputBuilder.test.ts"},{"assertionResults":[{"ancestorTitles":["assistant address tool-gate runtime adapter"],"fullName":"assistant address tool-gate runtime adapter does nothing when runAddressLane is true","status":"passed","title":"does nothing when runAddressLane is true","duration":1.3652000000000157,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant address tool-gate runtime adapter"],"fullName":"assistant address tool-gate runtime adapter logs skip and returns chat response when chat fallback handles","status":"passed","title":"logs skip and returns chat response when chat fallback handles","duration":0.6961000000000013,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant address tool-gate runtime adapter"],"fullName":"assistant address tool-gate runtime adapter logs skip and returns unhandled when mode is not chat","status":"passed","title":"logs skip and returns unhandled when mode is not chat","duration":0.2370999999999981,"failureMessages":[],"meta":{}}],"startTime":1775902595778,"endTime":1775902595781.237,"status":"passed","message":"","name":"X:/1C/NDC_1C/llm_normalizer/backend/tests/assistantAddressToolGateRuntimeAdapter.test.ts"},{"assertionResults":[{"ancestorTitles":["assistant address turn finalize runtime adapter"],"fullName":"assistant address turn finalize runtime adapter builds assistant item and passes expected log details into commit runtime","status":"passed","title":"builds assistant item and passes expected log details into commit runtime","duration":1.5289000000000215,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant address turn finalize runtime adapter"],"fullName":"assistant address turn finalize runtime adapter uses default commit runtime and returns conversation from stored session","status":"passed","title":"uses default commit runtime and returns conversation from stored session","duration":0.8054000000000201,"failureMessages":[],"meta":{}}],"startTime":1775902596026,"endTime":1775902596027.8054,"status":"passed","message":"","name":"X:/1C/NDC_1C/llm_normalizer/backend/tests/assistantAddressTurnFinalizeRuntimeAdapter.test.ts"},{"assertionResults":[{"ancestorTitles":["assistant answer encoding sanitizer"],"fullName":"assistant answer encoding sanitizer removes mojibake fragments from user-facing explainable answers","status":"passed","title":"removes mojibake fragments from user-facing explainable answers","duration":13.4983,"failureMessages":[],"meta":{}}],"startTime":1775902595068,"endTime":1775902595081.4983,"status":"passed","message":"","name":"X:/1C/NDC_1C/llm_normalizer/backend/tests/assistantAnswerEncodingSanitizer.test.ts"},{"assertionResults":[{"ancestorTitles":["assistant answer leakage guard"],"fullName":"assistant answer leakage guard removes raw technical refs from assistant reply but keeps structured refs in answer structure","status":"passed","title":"removes raw technical refs from assistant reply but keeps structured refs in answer structure","duration":17.104899999999986,"failureMessages":[],"meta":{}}],"startTime":1775902595025,"endTime":1775902595042.105,"status":"passed","message":"","name":"X:/1C/NDC_1C/llm_normalizer/backend/tests/assistantAnswerLeakageGuard.test.ts"},{"assertionResults":[{"ancestorTitles":["assistant answer package builder v11"],"fullName":"assistant answer package builder v11 builds baseline answer structure with unresolved mechanism","status":"passed","title":"builds baseline answer structure with unresolved mechanism","duration":1.602800000000002,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant answer package builder v11"],"fullName":"assistant answer package builder v11 adds claim-evidence links when enrichment is explicitly enabled","status":"passed","title":"adds claim-evidence links when enrichment is explicitly enabled","duration":0.6598999999999933,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant answer package builder v11"],"fullName":"assistant answer package builder v11 omits claim-evidence links when enrichment is disabled","status":"passed","title":"omits claim-evidence links when enrichment is disabled","duration":0.17320000000000846,"failureMessages":[],"meta":{}}],"startTime":1775902596079,"endTime":1775902596081.66,"status":"passed","message":"","name":"X:/1C/NDC_1C/llm_normalizer/backend/tests/assistantAnswerPackageBuilder.test.ts"},{"assertionResults":[{"ancestorTitles":["assistant answer policy v1.1"],"fullName":"assistant answer policy v1.1 keeps focused grounded answer direct and useful","status":"failed","title":"keeps focused grounded answer direct and useful","duration":5016.4271,"failureMessages":["Error: STACK_TRACE_ERROR\n at task (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:638:27)\n at Object. (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:662:16)\n at Object. (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:458:28)\n at chain (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:369:14)\n at X:\\1C\\NDC_1C\\llm_normalizer\\backend\\tests\\assistantAnswerPolicyV11.test.ts:56:3\n at file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:734:40\n at runWithSuite (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1849:8)\n at Object.collect (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:734:10)\n at Object.collect (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:738:54)\n at processTicksAndRejections (node:internal/process/task_queues:105:5)\n at collectTests (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1179:25)\n at startTests (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1817:17)\n at file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/vitest/dist/chunks/runBaseTests.9Ij9_de-.js:117:26\n at withEnv (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/vitest/dist/chunks/runBaseTests.9Ij9_de-.js:84:3)\n at run (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/vitest/dist/chunks/runBaseTests.9Ij9_de-.js:109:2)"],"meta":{}},{"ancestorTitles":["assistant answer policy v1.1"],"fullName":"assistant answer policy v1.1 renders broad partial answer with explicit limitations and concrete next steps","status":"failed","title":"renders broad partial answer with explicit limitations and concrete next steps","duration":5004.1241,"failureMessages":["Error: STACK_TRACE_ERROR\n at task (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:638:27)\n at Object. (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:662:16)\n at Object. (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:458:28)\n at chain (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:369:14)\n at X:\\1C\\NDC_1C\\llm_normalizer\\backend\\tests\\assistantAnswerPolicyV11.test.ts:85:3\n at file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:734:40\n at runWithSuite (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1849:8)\n at Object.collect (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:734:10)\n at Object.collect (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:738:54)\n at processTicksAndRejections (node:internal/process/task_queues:105:5)\n at collectTests (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1179:25)\n at startTests (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1817:17)\n at file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/vitest/dist/chunks/runBaseTests.9Ij9_de-.js:117:26\n at withEnv (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/vitest/dist/chunks/runBaseTests.9Ij9_de-.js:84:3)\n at run (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/vitest/dist/chunks/runBaseTests.9Ij9_de-.js:109:2)"],"meta":{}},{"ancestorTitles":["assistant answer policy v1.1"],"fullName":"assistant answer policy v1.1 uses domain-specific clarification prompts when support is insufficient","status":"failed","title":"uses domain-specific clarification prompts when support is insufficient","duration":5014.6939,"failureMessages":["Error: STACK_TRACE_ERROR\n at task (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:638:27)\n at Object. (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:662:16)\n at Object. (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:458:28)\n at chain (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:369:14)\n at X:\\1C\\NDC_1C\\llm_normalizer\\backend\\tests\\assistantAnswerPolicyV11.test.ts:113:3\n at file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:734:40\n at runWithSuite (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1849:8)\n at Object.collect (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:734:10)\n at Object.collect (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:738:54)\n at processTicksAndRejections (node:internal/process/task_queues:105:5)\n at collectTests (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1179:25)\n at startTests (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1817:17)\n at file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/vitest/dist/chunks/runBaseTests.9Ij9_de-.js:117:26\n at withEnv (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/vitest/dist/chunks/runBaseTests.9Ij9_de-.js:84:3)\n at run (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/vitest/dist/chunks/runBaseTests.9Ij9_de-.js:109:2)"],"meta":{}},{"ancestorTitles":["assistant answer policy v1.1"],"fullName":"assistant answer policy v1.1 does not fabricate mechanism when mechanism_note is unresolved","status":"passed","title":"does not fabricate mechanism when mechanism_note is unresolved","duration":35.83400000000074,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant answer policy v1.1"],"fullName":"assistant answer policy v1.1 preserves legacy reply path when policy flag is OFF","status":"failed","title":"preserves legacy reply path when policy flag is OFF","duration":5008.3699000000015,"failureMessages":["Error: STACK_TRACE_ERROR\n at task (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:638:27)\n at Object. (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:662:16)\n at Object. (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:458:28)\n at chain (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:369:14)\n at X:\\1C\\NDC_1C\\llm_normalizer\\backend\\tests\\assistantAnswerPolicyV11.test.ts:261:3\n at file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:734:40\n at runWithSuite (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1849:8)\n at Object.collect (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:734:10)\n at Object.collect (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:738:54)\n at processTicksAndRejections (node:internal/process/task_queues:105:5)\n at collectTests (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1179:25)\n at startTests (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1817:17)\n at file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/vitest/dist/chunks/runBaseTests.9Ij9_de-.js:117:26\n at withEnv (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/vitest/dist/chunks/runBaseTests.9Ij9_de-.js:84:3)\n at run (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/vitest/dist/chunks/runBaseTests.9Ij9_de-.js:109:2)"],"meta":{}}],"startTime":1775902593883,"endTime":1775902613963.3699,"status":"failed","message":"","name":"X:/1C/NDC_1C/llm_normalizer/backend/tests/assistantAnswerPolicyV11.test.ts"},{"assertionResults":[{"ancestorTitles":["assistant broad guard"],"fullName":"assistant broad guard keeps focused queries from degrading under broad guard","status":"failed","title":"keeps focused queries from degrading under broad guard","duration":5024.4774,"failureMessages":["Error: STACK_TRACE_ERROR\n at task (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:638:27)\n at Object. (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:662:16)\n at Object. (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:458:28)\n at chain (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:369:14)\n at X:\\1C\\NDC_1C\\llm_normalizer\\backend\\tests\\assistantBroadGuard.test.ts:51:3\n at file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:734:40\n at runWithSuite (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1849:8)\n at Object.collect (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:734:10)\n at Object.collect (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:738:54)\n at processTicksAndRejections (node:internal/process/task_queues:105:5)\n at collectTests (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1179:25)\n at startTests (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1817:17)\n at file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/vitest/dist/chunks/runBaseTests.9Ij9_de-.js:117:26\n at withEnv (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/vitest/dist/chunks/runBaseTests.9Ij9_de-.js:84:3)\n at run (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/vitest/dist/chunks/runBaseTests.9Ij9_de-.js:109:2)"],"meta":{}},{"ancestorTitles":["assistant broad guard"],"fullName":"assistant broad guard degrades broad ranking output to partial instead of deceptively strong factual","status":"failed","title":"degrades broad ranking output to partial instead of deceptively strong factual","duration":5006.629199999999,"failureMessages":["Error: STACK_TRACE_ERROR\n at task (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:638:27)\n at Object. (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:662:16)\n at Object. (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:458:28)\n at chain (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:369:14)\n at X:\\1C\\NDC_1C\\llm_normalizer\\backend\\tests\\assistantBroadGuard.test.ts:74:3\n at file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:734:40\n at runWithSuite (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1849:8)\n at Object.collect (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:734:10)\n at Object.collect (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:738:54)\n at processTicksAndRejections (node:internal/process/task_queues:105:5)\n at collectTests (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1179:25)\n at startTests (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1817:17)\n at file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/vitest/dist/chunks/runBaseTests.9Ij9_de-.js:117:26\n at withEnv (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/vitest/dist/chunks/runBaseTests.9Ij9_de-.js:84:3)\n at run (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/vitest/dist/chunks/runBaseTests.9Ij9_de-.js:109:2)"],"meta":{}},{"ancestorTitles":["assistant broad guard"],"fullName":"assistant broad guard returns clarification when broad query has insufficient support","status":"failed","title":"returns clarification when broad query has insufficient support","duration":5001.070900000001,"failureMessages":["Error: STACK_TRACE_ERROR\n at task (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:638:27)\n at Object. (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:662:16)\n at Object. (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:458:28)\n at chain (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:369:14)\n at X:\\1C\\NDC_1C\\llm_normalizer\\backend\\tests\\assistantBroadGuard.test.ts:101:3\n at file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:734:40\n at runWithSuite (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1849:8)\n at Object.collect (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:734:10)\n at Object.collect (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:738:54)\n at processTicksAndRejections (node:internal/process/task_queues:105:5)\n at collectTests (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1179:25)\n at startTests (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1817:17)\n at file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/vitest/dist/chunks/runBaseTests.9Ij9_de-.js:117:26\n at withEnv (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/vitest/dist/chunks/runBaseTests.9Ij9_de-.js:84:3)\n at run (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/vitest/dist/chunks/runBaseTests.9Ij9_de-.js:109:2)"],"meta":{}},{"ancestorTitles":["assistant broad guard"],"fullName":"assistant broad guard supports legacy behavior when broad guard flags are OFF","status":"failed","title":"supports legacy behavior when broad guard flags are OFF","duration":5010.965200000001,"failureMessages":["Error: STACK_TRACE_ERROR\n at task (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:638:27)\n at Object. (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:662:16)\n at Object. (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:458:28)\n at chain (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:369:14)\n at X:\\1C\\NDC_1C\\llm_normalizer\\backend\\tests\\assistantBroadGuard.test.ts:127:3\n at file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:734:40\n at runWithSuite (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1849:8)\n at Object.collect (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:734:10)\n at Object.collect (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:738:54)\n at processTicksAndRejections (node:internal/process/task_queues:105:5)\n at collectTests (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1179:25)\n at startTests (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1817:17)\n at file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/vitest/dist/chunks/runBaseTests.9Ij9_de-.js:117:26\n at withEnv (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/vitest/dist/chunks/runBaseTests.9Ij9_de-.js:84:3)\n at run (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/vitest/dist/chunks/runBaseTests.9Ij9_de-.js:109:2)"],"meta":{}}],"startTime":1775902593730,"endTime":1775902613773.965,"status":"failed","message":"","name":"X:/1C/NDC_1C/llm_normalizer/backend/tests/assistantBroadGuard.test.ts"},{"assertionResults":[{"ancestorTitles":["stage1 contract scaffolding"],"fullName":"stage1 contract scaffolding provides rubric v0.1 for accountant-facing metrics","status":"passed","title":"provides rubric v0.1 for accountant-facing metrics","duration":1.2434999999999832,"failureMessages":[],"meta":{}},{"ancestorTitles":["stage1 contract scaffolding"],"fullName":"stage1 contract scaffolding updates investigation_state with bounded fields","status":"passed","title":"updates investigation_state with bounded fields","duration":3.2404000000000224,"failureMessages":[],"meta":{}}],"startTime":1775902595287,"endTime":1775902595291.2405,"status":"passed","message":"","name":"X:/1C/NDC_1C/llm_normalizer/backend/tests/assistantContracts.test.ts"},{"assertionResults":[{"ancestorTitles":["assistant contracts bundle assembler"],"fullName":"assistant contracts bundle assembler assembles query/execution/coverage contracts with outcome class","status":"passed","title":"assembles query/execution/coverage contracts with outcome class","duration":1.2183999999999742,"failureMessages":[],"meta":{}}],"startTime":1775902596424,"endTime":1775902596425.2185,"status":"passed","message":"","name":"X:/1C/NDC_1C/llm_normalizer/backend/tests/assistantContractsBundleAssembler.test.ts"},{"assertionResults":[{"ancestorTitles":["assistant coverage-grounding module"],"fullName":"assistant coverage-grounding module extracts requirements from deterministic route summary","status":"passed","title":"extracts requirements from deterministic route summary","duration":1.6200999999999794,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant coverage-grounding module"],"fullName":"assistant coverage-grounding module evaluates coverage from retrieval outcomes","status":"passed","title":"evaluates coverage from retrieval outcomes","duration":0.5837999999999965,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant coverage-grounding module"],"fullName":"assistant coverage-grounding module produces route mismatch grounding when critical subject token is absent","status":"passed","title":"produces route mismatch grounding when critical subject token is absent","duration":0.32439999999999714,"failureMessages":[],"meta":{}}],"startTime":1775902596062,"endTime":1775902596064.5837,"status":"passed","message":"","name":"X:/1C/NDC_1C/llm_normalizer/backend/tests/assistantCoverageGrounding.test.ts"},{"assertionResults":[{"ancestorTitles":["stage4 graph critical supplemental coverage"],"fullName":"stage4 graph critical supplemental coverage captures neighbor branch lifting when linked branch is outside primary 97 scope","status":"passed","title":"captures neighbor branch lifting when linked branch is outside primary 97 scope","duration":226.5623,"failureMessages":[],"meta":{}},{"ancestorTitles":["stage4 graph critical supplemental coverage"],"fullName":"stage4 graph critical supplemental coverage surfaces cross-branch inconsistency as graph-critical conflict signal","status":"passed","title":"surfaces cross-branch inconsistency as graph-critical conflict signal","duration":16.55849999999998,"failureMessages":[],"meta":{}},{"ancestorTitles":["stage4 graph critical supplemental coverage"],"fullName":"stage4 graph critical supplemental coverage keeps terminal gap explicit instead of collapsing it into generic anomaly","status":"passed","title":"keeps terminal gap explicit instead of collapsing it into generic anomaly","duration":11.818299999999908,"failureMessages":[],"meta":{}},{"ancestorTitles":["stage4 graph critical supplemental coverage"],"fullName":"stage4 graph critical supplemental coverage shows ranking shift between graph OFF and graph ON for graph-critical contour","status":"passed","title":"shows ranking shift between graph OFF and graph ON for graph-critical contour","duration":44.477199999999925,"failureMessages":[],"meta":{}},{"ancestorTitles":["stage4 graph critical supplemental coverage"],"fullName":"stage4 graph critical supplemental coverage confirms multi-hop traversal is used for chain reasoning","status":"passed","title":"confirms multi-hop traversal is used for chain reasoning","duration":12.504000000000019,"failureMessages":[],"meta":{}},{"ancestorTitles":["stage4 graph critical supplemental coverage"],"fullName":"stage4 graph critical supplemental coverage keeps domain separation across deferred, fixed asset, vat, period close, bank and customer settlement","status":"passed","title":"keeps domain separation across deferred, fixed asset, vat, period close, bank and customer settlement","duration":88.96850000000006,"failureMessages":[],"meta":{}}],"startTime":1775902593694,"endTime":1775902594094.9685,"status":"passed","message":"","name":"X:/1C/NDC_1C/llm_normalizer/backend/tests/assistantDataLayerGraphCriticalCoverage.test.ts"},{"assertionResults":[{"ancestorTitles":["assistant data layer graph traversal integration"],"fullName":"assistant data layer graph traversal integration applies typed graph traversal for 97 lifecycle query when graph runtime is enabled","status":"passed","title":"applies typed graph traversal for 97 lifecycle query when graph runtime is enabled","duration":221.71869999999998,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant data layer graph traversal integration"],"fullName":"assistant data layer graph traversal integration maps VAT and period close prompts to graph target domains without changing prompt set","status":"passed","title":"maps VAT and period close prompts to graph target domains without changing prompt set","duration":18.95949999999999,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant data layer graph traversal integration"],"fullName":"assistant data layer graph traversal integration keeps graph traversal disabled when feature flag is off","status":"passed","title":"keeps graph traversal disabled when feature flag is off","duration":10.902199999999993,"failureMessages":[],"meta":{}}],"startTime":1775902593694,"endTime":1775902593944.902,"status":"passed","message":"","name":"X:/1C/NDC_1C/llm_normalizer/backend/tests/assistantDataLayerGraphTraversal.test.ts"},{"assertionResults":[{"ancestorTitles":["assistant data scope probe parser"],"fullName":"assistant data scope probe parser extracts organization name and guid from object-ref style row","status":"passed","title":"extracts organization name and guid from object-ref style row","duration":2.10450000000003,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant data scope probe parser"],"fullName":"assistant data scope probe parser extracts guid from hard-key payload (name is best-effort)","status":"passed","title":"extracts guid from hard-key payload (name is best-effort)","duration":0.40289999999998827,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant data scope probe parser"],"fullName":"assistant data scope probe parser resolves names by guid references from ref-name pairs","status":"passed","title":"resolves names by guid references from ref-name pairs","duration":0.4633999999999787,"failureMessages":[],"meta":{}}],"startTime":1775902595928,"endTime":1775902595930.4634,"status":"passed","message":"","name":"X:/1C/NDC_1C/llm_normalizer/backend/tests/assistantDataScopeProbeParser.test.ts"},{"assertionResults":[{"ancestorTitles":["assistant debug payload assembler"],"fullName":"assistant debug payload assembler builds deep debug payload with analysis context and optional sections","status":"passed","title":"builds deep debug payload with analysis context and optional sections","duration":2.151299999999992,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant debug payload assembler"],"fullName":"assistant debug payload assembler omits optional fields when they are not provided","status":"passed","title":"omits optional fields when they are not provided","duration":0.3902999999999963,"failureMessages":[],"meta":{}}],"startTime":1775902596247,"endTime":1775902596249.3904,"status":"passed","message":"","name":"X:/1C/NDC_1C/llm_normalizer/backend/tests/assistantDebugPayloadAssembler.test.ts"},{"assertionResults":[{"ancestorTitles":["assistant deep response assembler"],"fullName":"assistant deep response assembler strips technical tail and builds fallback answer structure when missing in composition","status":"passed","title":"strips technical tail and builds fallback answer structure when missing in composition","duration":1.5080000000000098,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant deep response assembler"],"fullName":"assistant deep response assembler uses provided composition answer structure and creates assistant conversation item","status":"passed","title":"uses provided composition answer structure and creates assistant conversation item","duration":0.9658999999999764,"failureMessages":[],"meta":{}}],"startTime":1775902595719,"endTime":1775902595720.9658,"status":"passed","message":"","name":"X:/1C/NDC_1C/llm_normalizer/backend/tests/assistantDeepResponseAssembler.test.ts"},{"assertionResults":[{"ancestorTitles":["assistant deep turn analysis attempt input builder"],"fullName":"assistant deep turn analysis attempt input builder builds analysis runtime callbacks and delegates stage payload mapping","status":"passed","title":"builds analysis runtime callbacks and delegates stage payload mapping","duration":3.91040000000001,"failureMessages":[],"meta":{}}],"startTime":1775902595285,"endTime":1775902595288.9104,"status":"passed","message":"","name":"X:/1C/NDC_1C/llm_normalizer/backend/tests/assistantDeepTurnAnalysisAttemptInputBuilder.test.ts"},{"assertionResults":[{"ancestorTitles":["assistant deep turn analysis attempt runtime adapter"],"fullName":"assistant deep turn analysis attempt runtime adapter wires deep-analysis callbacks through delegated runtime","status":"passed","title":"wires deep-analysis callbacks through delegated runtime","duration":3.6946000000000083,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant deep turn analysis attempt runtime adapter"],"fullName":"assistant deep turn analysis attempt runtime adapter forwards composition feature flags and investigation state","status":"passed","title":"forwards composition feature flags and investigation state","duration":7.3600999999999885,"failureMessages":[],"meta":{}}],"startTime":1775902595183,"endTime":1775902595194.36,"status":"passed","message":"","name":"X:/1C/NDC_1C/llm_normalizer/backend/tests/assistantDeepTurnAnalysisAttemptRuntimeAdapter.test.ts"},{"assertionResults":[{"ancestorTitles":["assistant deep turn analysis runtime adapter"],"fullName":"assistant deep turn analysis runtime adapter orchestrates deep pipeline steps in deterministic order","status":"passed","title":"orchestrates deep pipeline steps in deterministic order","duration":2.4776999999999987,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant deep turn analysis runtime adapter"],"fullName":"assistant deep turn analysis runtime adapter passes null business scope when not resolved","status":"passed","title":"passes null business scope when not resolved","duration":1.2525000000000261,"failureMessages":[],"meta":{}}],"startTime":1775902595594,"endTime":1775902595597.2524,"status":"passed","message":"","name":"X:/1C/NDC_1C/llm_normalizer/backend/tests/assistantDeepTurnAnalysisRuntimeAdapter.test.ts"},{"assertionResults":[{"ancestorTitles":["assistant deep turn attempt input builder"],"fullName":"assistant deep turn attempt input builder builds normalization runtime input from turn fields","status":"passed","title":"builds normalization runtime input from turn fields","duration":1.1916999999999973,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant deep turn attempt input builder"],"fullName":"assistant deep turn attempt input builder builds analysis and response attempt inputs from normalization runtime","status":"passed","title":"builds analysis and response attempt inputs from normalization runtime","duration":1.208500000000015,"failureMessages":[],"meta":{}}],"startTime":1775902596016,"endTime":1775902596019.2085,"status":"passed","message":"","name":"X:/1C/NDC_1C/llm_normalizer/backend/tests/assistantDeepTurnAttemptInputBuilder.test.ts"},{"assertionResults":[{"ancestorTitles":["assistant deep turn attempt runtime adapter"],"fullName":"assistant deep turn attempt runtime adapter orchestrates normalization, analysis and response attempts in order","status":"passed","title":"orchestrates normalization, analysis and response attempts in order","duration":2.4102000000000032,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant deep turn attempt runtime adapter"],"fullName":"assistant deep turn attempt runtime adapter computes followupApplied=false when followup usage is absent","status":"passed","title":"computes followupApplied=false when followup usage is absent","duration":1.8680999999999983,"failureMessages":[],"meta":{}}],"startTime":1775902595655,"endTime":1775902595658.8682,"status":"passed","message":"","name":"X:/1C/NDC_1C/llm_normalizer/backend/tests/assistantDeepTurnAttemptRuntimeAdapter.test.ts"},{"assertionResults":[{"ancestorTitles":["assistant deep turn composition runtime adapter"],"fullName":"assistant deep turn composition runtime adapter uses followup domain hint and company-anchor period signal","status":"passed","title":"uses followup domain hint and company-anchor period signal","duration":1.2164999999999964,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant deep turn composition runtime adapter"],"fullName":"assistant deep turn composition runtime adapter falls back to explicit period from normalized payload when anchors are absent","status":"passed","title":"falls back to explicit period from normalized payload when anchors are absent","duration":0.3966999999999814,"failureMessages":[],"meta":{}}],"startTime":1775902596394,"endTime":1775902596396.3967,"status":"passed","message":"","name":"X:/1C/NDC_1C/llm_normalizer/backend/tests/assistantDeepTurnCompositionRuntimeAdapter.test.ts"},{"assertionResults":[{"ancestorTitles":["assistant deep turn context runtime adapter"],"fullName":"assistant deep turn context runtime adapter assembles context in deterministic order and propagates followup flag","status":"passed","title":"assembles context in deterministic order and propagates followup flag","duration":1.3926000000000158,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant deep turn context runtime adapter"],"fullName":"assistant deep turn context runtime adapter drops unknown inferred domain and disables live temporal hint when context is inactive","status":"passed","title":"drops unknown inferred domain and disables live temporal hint when context is inactive","duration":0.23980000000000246,"failureMessages":[],"meta":{}}],"startTime":1775902596313,"endTime":1775902596315.2397,"status":"passed","message":"","name":"X:/1C/NDC_1C/llm_normalizer/backend/tests/assistantDeepTurnContextRuntimeAdapter.test.ts"},{"assertionResults":[{"ancestorTitles":["assistant deep turn finalize runtime adapter"],"fullName":"assistant deep turn finalize runtime adapter commits assistant turn and builds response with committed conversation","status":"passed","title":"commits assistant turn and builds response with committed conversation","duration":1.2723000000000013,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant deep turn finalize runtime adapter"],"fullName":"assistant deep turn finalize runtime adapter uses default commit/response functions when custom hooks are not provided","status":"passed","title":"uses default commit/response functions when custom hooks are not provided","duration":0.7680000000000007,"failureMessages":[],"meta":{}}],"startTime":1775902596195,"endTime":1775902596196.768,"status":"passed","message":"","name":"X:/1C/NDC_1C/llm_normalizer/backend/tests/assistantDeepTurnFinalizeRuntimeAdapter.test.ts"},{"assertionResults":[{"ancestorTitles":["assistant deep turn grounding runtime adapter"],"fullName":"assistant deep turn grounding runtime adapter runs audits, coverage-grounding pipeline and eligibility overlay in stable order","status":"passed","title":"runs audits, coverage-grounding pipeline and eligibility overlay in stable order","duration":2.1487999999999943,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant deep turn grounding runtime adapter"],"fullName":"assistant deep turn grounding runtime adapter threads default pipeline output through without custom hooks","status":"passed","title":"threads default pipeline output through without custom hooks","duration":0.522500000000008,"failureMessages":[],"meta":{}}],"startTime":1775902596018,"endTime":1775902596020.5225,"status":"passed","message":"","name":"X:/1C/NDC_1C/llm_normalizer/backend/tests/assistantDeepTurnGroundingRuntimeAdapter.test.ts"},{"assertionResults":[{"ancestorTitles":["assistant deep turn guard runtime adapter"],"fullName":"assistant deep turn guard runtime adapter runs retrieval guards in expected order and threads outputs","status":"passed","title":"runs retrieval guards in expected order and threads outputs","duration":1.350200000000001,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant deep turn guard runtime adapter"],"fullName":"assistant deep turn guard runtime adapter evaluates grounding eligibility and applies status overlay","status":"passed","title":"evaluates grounding eligibility and applies status overlay","duration":0.31749999999999545,"failureMessages":[],"meta":{}}],"startTime":1775902596295,"endTime":1775902596296.35,"status":"passed","message":"","name":"X:/1C/NDC_1C/llm_normalizer/backend/tests/assistantDeepTurnGuardRuntimeAdapter.test.ts"},{"assertionResults":[{"ancestorTitles":["assistant deep turn input builder"],"fullName":"assistant deep turn input builder applies stable defaults for optional composition and followup fields","status":"passed","title":"applies stable defaults for optional composition and followup fields","duration":1.1329999999999814,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant deep turn input builder"],"fullName":"assistant deep turn input builder preserves explicit composition fields and normalizes unit ids array","status":"passed","title":"preserves explicit composition fields and normalizes unit ids array","duration":0.30759999999997945,"failureMessages":[],"meta":{}}],"startTime":1775902596380,"endTime":1775902596381.3076,"status":"passed","message":"","name":"X:/1C/NDC_1C/llm_normalizer/backend/tests/assistantDeepTurnInputBuilder.test.ts"},{"assertionResults":[{"ancestorTitles":["assistant deep turn normalization runtime adapter"],"fullName":"assistant deep turn normalization runtime adapter uses followup state binding when feature flags are enabled and state exists","status":"passed","title":"uses followup state binding when feature flags are enabled and state exists","duration":2.2735000000000127,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant deep turn normalization runtime adapter"],"fullName":"assistant deep turn normalization runtime adapter falls back to raw user message when followup binding is disabled","status":"passed","title":"falls back to raw user message when followup binding is disabled","duration":0.5567000000000064,"failureMessages":[],"meta":{}}],"startTime":1775902595401,"endTime":1775902595403.5566,"status":"passed","message":"","name":"X:/1C/NDC_1C/llm_normalizer/backend/tests/assistantDeepTurnNormalizationRuntimeAdapter.test.ts"},{"assertionResults":[{"ancestorTitles":["assistant deep turn packaging"],"fullName":"assistant deep turn packaging assembles deep artifacts, debug payload and processed log in one call","status":"passed","title":"assembles deep artifacts, debug payload and processed log in one call","duration":2.6593000000000018,"failureMessages":[],"meta":{}}],"startTime":1775902595897,"endTime":1775902595899.6592,"status":"passed","message":"","name":"X:/1C/NDC_1C/llm_normalizer/backend/tests/assistantDeepTurnPackaging.test.ts"},{"assertionResults":[{"ancestorTitles":["assistant deep turn packaging runtime adapter"],"fullName":"assistant deep turn packaging runtime adapter executes pre-packaging, snapshot, persist, input-build and assembly in stable order","status":"passed","title":"executes pre-packaging, snapshot, persist, input-build and assembly in stable order","duration":1.858099999999979,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant deep turn packaging runtime adapter"],"fullName":"assistant deep turn packaging runtime adapter does not persist investigation snapshot when feature is disabled","status":"passed","title":"does not persist investigation snapshot when feature is disabled","duration":0.25319999999999254,"failureMessages":[],"meta":{}}],"startTime":1775902596207,"endTime":1775902596209.2532,"status":"passed","message":"","name":"X:/1C/NDC_1C/llm_normalizer/backend/tests/assistantDeepTurnPackagingRuntimeAdapter.test.ts"},{"assertionResults":[{"ancestorTitles":["assistant deep turn plan runtime adapter"],"fullName":"assistant deep turn plan runtime adapter builds execution plan through extraction, enforcement and guard hints in stable order","status":"passed","title":"builds execution plan through extraction, enforcement and guard hints in stable order","duration":1.4505000000000052,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant deep turn plan runtime adapter"],"fullName":"assistant deep turn plan runtime adapter preserves empty execution plan end-to-end","status":"passed","title":"preserves empty execution plan end-to-end","duration":0.19660000000001787,"failureMessages":[],"meta":{}}],"startTime":1775902596072,"endTime":1775902596073.4504,"status":"passed","message":"","name":"X:/1C/NDC_1C/llm_normalizer/backend/tests/assistantDeepTurnPlanRuntimeAdapter.test.ts"},{"assertionResults":[{"ancestorTitles":["assistant deep turn pre-packaging context"],"fullName":"assistant deep turn pre-packaging context builds all pre-packaging fields with active analysis context","status":"passed","title":"builds all pre-packaging fields with active analysis context","duration":1.2774,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant deep turn pre-packaging context"],"fullName":"assistant deep turn pre-packaging context returns null analysis context when runtime context is inactive","status":"passed","title":"returns null analysis context when runtime context is inactive","duration":0.2506999999999948,"failureMessages":[],"meta":{}}],"startTime":1775902596257,"endTime":1775902596259.2507,"status":"passed","message":"","name":"X:/1C/NDC_1C/llm_normalizer/backend/tests/assistantDeepTurnPrePackagingContext.test.ts"},{"assertionResults":[{"ancestorTitles":["assistant deep turn response attempt runtime adapter"],"fullName":"assistant deep turn response attempt runtime adapter maps deep-analysis runtime output into response runtime input","status":"passed","title":"maps deep-analysis runtime output into response runtime input","duration":2.856500000000011,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant deep turn response attempt runtime adapter"],"fullName":"assistant deep turn response attempt runtime adapter forwards callbacks and state flags","status":"passed","title":"forwards callbacks and state flags","duration":0.41669999999999163,"failureMessages":[],"meta":{}}],"startTime":1775902595712,"endTime":1775902595715.4167,"status":"passed","message":"","name":"X:/1C/NDC_1C/llm_normalizer/backend/tests/assistantDeepTurnResponseAttemptRuntimeAdapter.test.ts"},{"assertionResults":[{"ancestorTitles":["assistant deep turn response builder"],"fullName":"assistant deep turn response builder builds canonical assistant message response envelope","status":"passed","title":"builds canonical assistant message response envelope","duration":1.2424999999999784,"failureMessages":[],"meta":{}}],"startTime":1775902596383,"endTime":1775902596384.2424,"status":"passed","message":"","name":"X:/1C/NDC_1C/llm_normalizer/backend/tests/assistantDeepTurnResponseBuilder.test.ts"},{"assertionResults":[{"ancestorTitles":["assistant deep turn response runtime adapter"],"fullName":"assistant deep turn response runtime adapter wires packaging output into deep finalization","status":"passed","title":"wires packaging output into deep finalization","duration":2.893299999999982,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant deep turn response runtime adapter"],"fullName":"assistant deep turn response runtime adapter passes feature flags and followup flags into packaging stage","status":"passed","title":"passes feature flags and followup flags into packaging stage","duration":0.3918000000000177,"failureMessages":[],"meta":{}}],"startTime":1775902595697,"endTime":1775902595700.3918,"status":"passed","message":"","name":"X:/1C/NDC_1C/llm_normalizer/backend/tests/assistantDeepTurnResponseRuntimeAdapter.test.ts"},{"assertionResults":[{"ancestorTitles":["assistant deep turn response runtime input builder"],"fullName":"assistant deep turn response runtime input builder maps analysis runtime into response runtime contract","status":"passed","title":"maps analysis runtime into response runtime contract","duration":2.1306000000000154,"failureMessages":[],"meta":{}}],"startTime":1775902596153,"endTime":1775902596155.1306,"status":"passed","message":"","name":"X:/1C/NDC_1C/llm_normalizer/backend/tests/assistantDeepTurnResponseRuntimeInputBuilder.test.ts"},{"assertionResults":[{"ancestorTitles":["assistant deep turn retrieval runtime adapter"],"fullName":"assistant deep turn retrieval runtime adapter handles skipped, executed and failed plan items with stable call records","status":"passed","title":"handles skipped, executed and failed plan items with stable call records","duration":1.9827999999999975,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant deep turn retrieval runtime adapter"],"fullName":"assistant deep turn retrieval runtime adapter passes live temporal hint into route runtime execution","status":"passed","title":"passes live temporal hint into route runtime execution","duration":0.18500000000000227,"failureMessages":[],"meta":{}}],"startTime":1775902596107,"endTime":1775902596109.185,"status":"passed","message":"","name":"X:/1C/NDC_1C/llm_normalizer/backend/tests/assistantDeepTurnRetrievalRuntimeAdapter.test.ts"},{"assertionResults":[{"ancestorTitles":["assistant mode API"],"fullName":"assistant mode API processes message and returns assistant response with debug payload","status":"passed","title":"processes message and returns assistant response with debug payload","duration":269.21039999999994,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant mode API"],"fullName":"assistant mode API keeps session-scoped history and returns it via session endpoint","status":"passed","title":"keeps session-scoped history and returns it via session endpoint","duration":147.62580000000003,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant mode API"],"fullName":"assistant mode API recovers company-specific scope for settlement follow-up without explicit month anchor","status":"failed","title":"recovers company-specific scope for settlement follow-up without explicit month anchor","duration":5006.2452,"failureMessages":["Error: STACK_TRACE_ERROR\n at task (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:638:27)\n at Object. (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:662:16)\n at Object. (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:458:28)\n at chain (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:369:14)\n at X:\\1C\\NDC_1C\\llm_normalizer\\backend\\tests\\assistantEndpoint.test.ts:79:3\n at file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:734:40\n at runWithSuite (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1849:8)\n at Object.collect (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:734:10)\n at Object.collect (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:738:54)\n at processTicksAndRejections (node:internal/process/task_queues:105:5)\n at collectTests (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1179:25)\n at startTests (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1817:17)\n at file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/vitest/dist/chunks/runBaseTests.9Ij9_de-.js:117:26\n at withEnv (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/vitest/dist/chunks/runBaseTests.9Ij9_de-.js:84:3)\n at run (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/vitest/dist/chunks/runBaseTests.9Ij9_de-.js:109:2)"],"meta":{}},{"ancestorTitles":["assistant mode API"],"fullName":"assistant mode API executes factual retrieval for routed fragments","status":"failed","title":"executes factual retrieval for routed fragments","duration":5015.116499999999,"failureMessages":["Error: STACK_TRACE_ERROR\n at task (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:638:27)\n at Object. (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:662:16)\n at Object. (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:458:28)\n at chain (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:369:14)\n at X:\\1C\\NDC_1C\\llm_normalizer\\backend\\tests\\assistantEndpoint.test.ts:110:3\n at file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:734:40\n at runWithSuite (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1849:8)\n at Object.collect (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:734:10)\n at Object.collect (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:738:54)\n at processTicksAndRejections (node:internal/process/task_queues:105:5)\n at collectTests (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1179:25)\n at startTests (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1817:17)\n at file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/vitest/dist/chunks/runBaseTests.9Ij9_de-.js:117:26\n at withEnv (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/vitest/dist/chunks/runBaseTests.9Ij9_de-.js:84:3)\n at run (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/vitest/dist/chunks/runBaseTests.9Ij9_de-.js:109:2)"],"meta":{}},{"ancestorTitles":["assistant mode API"],"fullName":"assistant mode API keeps in-domain translit queries in scope and routed","status":"passed","title":"keeps in-domain translit queries in scope and routed","duration":129.38659999999982,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant mode API"],"fullName":"assistant mode API avoids false route mismatch when supported evidence exists for bounded answer","status":"failed","title":"avoids false route mismatch when supported evidence exists for bounded answer","duration":5020.3379,"failureMessages":["Error: STACK_TRACE_ERROR\n at task (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:638:27)\n at Object. (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:662:16)\n at Object. (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:458:28)\n at chain (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:369:14)\n at X:\\1C\\NDC_1C\\llm_normalizer\\backend\\tests\\assistantEndpoint.test.ts:171:3\n at file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:734:40\n at runWithSuite (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1849:8)\n at Object.collect (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:734:10)\n at Object.collect (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:738:54)\n at processTicksAndRejections (node:internal/process/task_queues:105:5)\n at collectTests (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1179:25)\n at startTests (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1817:17)\n at file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/vitest/dist/chunks/runBaseTests.9Ij9_de-.js:117:26\n at withEnv (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/vitest/dist/chunks/runBaseTests.9Ij9_de-.js:84:3)\n at run (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/vitest/dist/chunks/runBaseTests.9Ij9_de-.js:109:2)"],"meta":{}},{"ancestorTitles":["assistant mode API"],"fullName":"assistant mode API returns bounded answer when critical domain token has weak grounding","status":"passed","title":"returns bounded answer when critical domain token has weak grounding","duration":133.5036,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant mode API"],"fullName":"assistant mode API applies semantic narrowing profile for hybrid retrieval without GUID","status":"failed","title":"applies semantic narrowing profile for hybrid retrieval without GUID","duration":5013.816300000002,"failureMessages":["Error: STACK_TRACE_ERROR\n at task (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:638:27)\n at Object. (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:662:16)\n at Object. (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:458:28)\n at chain (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:369:14)\n at X:\\1C\\NDC_1C\\llm_normalizer\\backend\\tests\\assistantEndpoint.test.ts:209:3\n at file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:734:40\n at runWithSuite (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1849:8)\n at Object.collect (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:734:10)\n at Object.collect (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:738:54)\n at processTicksAndRejections (node:internal/process/task_queues:105:5)\n at collectTests (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1179:25)\n at startTests (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1817:17)\n at file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/vitest/dist/chunks/runBaseTests.9Ij9_de-.js:117:26\n at withEnv (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/vitest/dist/chunks/runBaseTests.9Ij9_de-.js:84:3)\n at run (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/vitest/dist/chunks/runBaseTests.9Ij9_de-.js:109:2)"],"meta":{}},{"ancestorTitles":["assistant mode API"],"fullName":"assistant mode API writes one persistent JSON log file per session","status":"passed","title":"writes one persistent JSON log file per session","duration":131.58539999999994,"failureMessages":[],"meta":{}}],"startTime":1775902594674,"endTime":1775902615541.5854,"status":"failed","message":"","name":"X:/1C/NDC_1C/llm_normalizer/backend/tests/assistantEndpoint.test.ts"},{"assertionResults":[{"ancestorTitles":["assistant Stage 1 eval harness"],"fullName":"assistant Stage 1 eval harness runs assistant_stage1 harness and returns raw metrics + rubric bands","status":"failed","title":"runs assistant_stage1 harness and returns raw metrics + rubric bands","duration":5026.4931,"failureMessages":["Error: STACK_TRACE_ERROR\n at task (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:638:27)\n at Object. (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:662:16)\n at Object. (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:458:28)\n at chain (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:369:14)\n at X:\\1C\\NDC_1C\\llm_normalizer\\backend\\tests\\assistantEvalHarness.test.ts:59:3\n at file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:734:40\n at runWithSuite (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1849:8)\n at Object.collect (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:734:10)\n at Object.collect (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:738:54)\n at processTicksAndRejections (node:internal/process/task_queues:105:5)\n at collectTests (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1179:25)\n at startTests (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1817:17)\n at file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/vitest/dist/chunks/runBaseTests.9Ij9_de-.js:117:26\n at withEnv (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/vitest/dist/chunks/runBaseTests.9Ij9_de-.js:84:3)\n at run (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/vitest/dist/chunks/runBaseTests.9Ij9_de-.js:109:2)"],"meta":{}},{"ancestorTitles":["assistant Stage 1 eval harness"],"fullName":"assistant Stage 1 eval harness loads canonical suite metadata and keeps it stable","status":"failed","title":"loads canonical suite metadata and keeps it stable","duration":5004.9193,"failureMessages":["Error: STACK_TRACE_ERROR\n at task (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:638:27)\n at Object. (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:662:16)\n at Object. (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:458:28)\n at chain (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:369:14)\n at X:\\1C\\NDC_1C\\llm_normalizer\\backend\\tests\\assistantEvalHarness.test.ts:97:3\n at file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:734:40\n at runWithSuite (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1849:8)\n at Object.collect (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:734:10)\n at Object.collect (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:738:54)\n at processTicksAndRejections (node:internal/process/task_queues:105:5)\n at collectTests (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1179:25)\n at startTests (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1817:17)\n at file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/vitest/dist/chunks/runBaseTests.9Ij9_de-.js:117:26\n at withEnv (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/vitest/dist/chunks/runBaseTests.9Ij9_de-.js:84:3)\n at run (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/vitest/dist/chunks/runBaseTests.9Ij9_de-.js:109:2)"],"meta":{}},{"ancestorTitles":["assistant Stage 1 eval harness"],"fullName":"assistant Stage 1 eval harness handles follow-up cases as dedicated subset","status":"failed","title":"handles follow-up cases as dedicated subset","duration":5013.5543,"failureMessages":["Error: STACK_TRACE_ERROR\n at task (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:638:27)\n at Object. (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:662:16)\n at Object. (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:458:28)\n at chain (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:369:14)\n at X:\\1C\\NDC_1C\\llm_normalizer\\backend\\tests\\assistantEvalHarness.test.ts:121:3\n at file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:734:40\n at runWithSuite (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1849:8)\n at Object.collect (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:734:10)\n at Object.collect (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:738:54)\n at processTicksAndRejections (node:internal/process/task_queues:105:5)\n at collectTests (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1179:25)\n at startTests (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1817:17)\n at file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/vitest/dist/chunks/runBaseTests.9Ij9_de-.js:117:26\n at withEnv (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/vitest/dist/chunks/runBaseTests.9Ij9_de-.js:84:3)\n at run (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/vitest/dist/chunks/runBaseTests.9Ij9_de-.js:109:2)"],"meta":{}},{"ancestorTitles":["assistant Stage 1 eval harness"],"fullName":"assistant Stage 1 eval harness builds comparison artifact from baseline and current runs","status":"failed","title":"builds comparison artifact from baseline and current runs","duration":5011.050600000002,"failureMessages":["Error: STACK_TRACE_ERROR\n at task (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:638:27)\n at Object. (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:662:16)\n at Object. (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:458:28)\n at chain (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:369:14)\n at X:\\1C\\NDC_1C\\llm_normalizer\\backend\\tests\\assistantEvalHarness.test.ts:143:3\n at file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:734:40\n at runWithSuite (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1849:8)\n at Object.collect (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:734:10)\n at Object.collect (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:738:54)\n at processTicksAndRejections (node:internal/process/task_queues:105:5)\n at collectTests (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1179:25)\n at startTests (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1817:17)\n at file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/vitest/dist/chunks/runBaseTests.9Ij9_de-.js:117:26\n at withEnv (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/vitest/dist/chunks/runBaseTests.9Ij9_de-.js:84:3)\n at run (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/vitest/dist/chunks/runBaseTests.9Ij9_de-.js:109:2)"],"meta":{}},{"ancestorTitles":["assistant Stage 1 eval harness"],"fullName":"assistant Stage 1 eval harness keeps legacy eval path unchanged by default","status":"passed","title":"keeps legacy eval path unchanged by default","duration":130.20730000000185,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant Stage 1 eval harness"],"fullName":"assistant Stage 1 eval harness respects accountant eval feature flag OFF/ON","status":"failed","title":"respects accountant eval feature flag OFF/ON","duration":5004.797600000002,"failureMessages":["Error: STACK_TRACE_ERROR\n at task (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:638:27)\n at Object. (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:662:16)\n at Object. (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:458:28)\n at chain (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:369:14)\n at X:\\1C\\NDC_1C\\llm_normalizer\\backend\\tests\\assistantEvalHarness.test.ts:202:3\n at file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:734:40\n at runWithSuite (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1849:8)\n at Object.collect (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:734:10)\n at Object.collect (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:738:54)\n at processTicksAndRejections (node:internal/process/task_queues:105:5)\n at collectTests (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1179:25)\n at startTests (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1817:17)\n at file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/vitest/dist/chunks/runBaseTests.9Ij9_de-.js:117:26\n at withEnv (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/vitest/dist/chunks/runBaseTests.9Ij9_de-.js:84:3)\n at run (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/vitest/dist/chunks/runBaseTests.9Ij9_de-.js:109:2)"],"meta":{}}],"startTime":1775902593732,"endTime":1775902618923.7976,"status":"failed","message":"","name":"X:/1C/NDC_1C/llm_normalizer/backend/tests/assistantEvalHarness.test.ts"},{"assertionResults":[{"ancestorTitles":["assistant evidence bundle assembler"],"fullName":"assistant evidence bundle assembler builds evidence contract and retrieval status from the same retrieval set","status":"passed","title":"builds evidence contract and retrieval status from the same retrieval set","duration":1.8722999999999956,"failureMessages":[],"meta":{}}],"startTime":1775902596329,"endTime":1775902596330.8723,"status":"passed","message":"","name":"X:/1C/NDC_1C/llm_normalizer/backend/tests/assistantEvidenceBundleAssembler.test.ts"},{"assertionResults":[{"ancestorTitles":["assistant follow-up state binding"],"fullName":"assistant follow-up state binding applies investigation_state binding in follow-up flow when flags are ON","status":"failed","title":"applies investigation_state binding in follow-up flow when flags are ON","duration":1038.4133,"failureMessages":["AssertionError: expected undefined to be 1 // Object.is equality\n at X:\\1C\\NDC_1C\\llm_normalizer\\backend\\tests\\assistantFollowupStateBinding.test.ts:72:72\n at processTicksAndRejections (node:internal/process/task_queues:105:5)\n at file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:752:20"],"meta":{}},{"ancestorTitles":["assistant follow-up state binding"],"fullName":"assistant follow-up state binding does not apply follow-up binding when binding flag is OFF","status":"passed","title":"does not apply follow-up binding when binding flag is OFF","duration":119.9556,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant follow-up state binding"],"fullName":"assistant follow-up state binding keeps legacy-like behavior when investigation state flag is OFF","status":"passed","title":"keeps legacy-like behavior when investigation state flag is OFF","duration":185.4239,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant follow-up state binding"],"fullName":"assistant follow-up state binding applies problem continuity hints only when continuity flag is ON and follow-up has no strong new anchors","status":"failed","title":"applies problem continuity hints only when continuity flag is ON and follow-up has no strong new anchors","duration":114.07940000000008,"failureMessages":["AssertionError: expected undefined to be truthy\n at X:\\1C\\NDC_1C\\llm_normalizer\\backend\\tests\\assistantFollowupStateBinding.test.ts:151:80\n at processTicksAndRejections (node:internal/process/task_queues:105:5)\n at file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:752:20"],"meta":{}},{"ancestorTitles":["assistant follow-up state binding"],"fullName":"assistant follow-up state binding does not apply follow-up continuity when user gives strong new anchors","status":"failed","title":"does not apply follow-up continuity when user gives strong new anchors","duration":5012.5635999999995,"failureMessages":["Error: STACK_TRACE_ERROR\n at task (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:638:27)\n at Object. (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:662:16)\n at Object. (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:458:28)\n at chain (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:369:14)\n at X:\\1C\\NDC_1C\\llm_normalizer\\backend\\tests\\assistantFollowupStateBinding.test.ts:167:3\n at file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:734:40\n at runWithSuite (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1849:8)\n at Object.collect (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:734:10)\n at Object.collect (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:738:54)\n at processTicksAndRejections (node:internal/process/task_queues:105:5)\n at collectTests (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1179:25)\n at startTests (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1817:17)\n at file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/vitest/dist/chunks/runBaseTests.9Ij9_de-.js:117:26\n at withEnv (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/vitest/dist/chunks/runBaseTests.9Ij9_de-.js:84:3)\n at run (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/vitest/dist/chunks/runBaseTests.9Ij9_de-.js:109:2)"],"meta":{}},{"ancestorTitles":["assistant follow-up state binding"],"fullName":"assistant follow-up state binding isolates scope for independent cross-domain turn and does not carry stale period/domain","status":"failed","title":"isolates scope for independent cross-domain turn and does not carry stale period/domain","duration":5001.812499999999,"failureMessages":["Error: STACK_TRACE_ERROR\n at task (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:638:27)\n at Object. (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:662:16)\n at Object. (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:458:28)\n at chain (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:369:14)\n at X:\\1C\\NDC_1C\\llm_normalizer\\backend\\tests\\assistantFollowupStateBinding.test.ts:197:3\n at file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:734:40\n at runWithSuite (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1849:8)\n at Object.collect (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:734:10)\n at Object.collect (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:738:54)\n at processTicksAndRejections (node:internal/process/task_queues:105:5)\n at collectTests (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1179:25)\n at startTests (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1817:17)\n at file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/vitest/dist/chunks/runBaseTests.9Ij9_de-.js:117:26\n at withEnv (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/vitest/dist/chunks/runBaseTests.9Ij9_de-.js:84:3)\n at run (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/vitest/dist/chunks/runBaseTests.9Ij9_de-.js:109:2)"],"meta":{}},{"ancestorTitles":["assistant follow-up state binding"],"fullName":"assistant follow-up state binding rebinds follow-up domain away from settlements on fixed-asset amortization query","status":"failed","title":"rebinds follow-up domain away from settlements on fixed-asset amortization query","duration":246.91679999999906,"failureMessages":["AssertionError: expected '' to match /fixed_asset_amortization|month_close…/i\n at X:\\1C\\NDC_1C\\llm_normalizer\\backend\\tests\\assistantFollowupStateBinding.test.ts:268:26\n at processTicksAndRejections (node:internal/process/task_queues:105:5)\n at file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:752:20"],"meta":{}},{"ancestorTitles":["assistant follow-up state binding"],"fullName":"assistant follow-up state binding keeps UTF-8 follow-up period refinement in-scope with soft continuity hints","status":"failed","title":"keeps UTF-8 follow-up period refinement in-scope with soft continuity hints","duration":5008.5201,"failureMessages":["Error: STACK_TRACE_ERROR\n at task (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:638:27)\n at Object. (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:662:16)\n at Object. (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:458:28)\n at chain (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:369:14)\n at X:\\1C\\NDC_1C\\llm_normalizer\\backend\\tests\\assistantFollowupStateBinding.test.ts:274:3\n at file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:734:40\n at runWithSuite (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1849:8)\n at Object.collect (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:734:10)\n at Object.collect (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:738:54)\n at processTicksAndRejections (node:internal/process/task_queues:105:5)\n at collectTests (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1179:25)\n at startTests (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1817:17)\n at file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/vitest/dist/chunks/runBaseTests.9Ij9_de-.js:117:26\n at withEnv (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/vitest/dist/chunks/runBaseTests.9Ij9_de-.js:84:3)\n at run (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/vitest/dist/chunks/runBaseTests.9Ij9_de-.js:109:2)"],"meta":{}}],"startTime":1775902593733,"endTime":1775902610460.52,"status":"failed","message":"","name":"X:/1C/NDC_1C/llm_normalizer/backend/tests/assistantFollowupStateBinding.test.ts"},{"assertionResults":[{"ancestorTitles":["assistant graph-backed answer mode v1"],"fullName":"assistant graph-backed answer mode v1 renders user-facing causal graph explanation without internal graph labels","status":"passed","title":"renders user-facing causal graph explanation without internal graph labels","duration":20.835800000000006,"failureMessages":[],"meta":{}}],"startTime":1775902595030,"endTime":1775902595050.8357,"status":"passed","message":"","name":"X:/1C/NDC_1C/llm_normalizer/backend/tests/assistantGraphBackedAnswerV1.test.ts"},{"assertionResults":[{"ancestorTitles":["assistant investigation state runtime adapter"],"fullName":"assistant investigation state runtime adapter returns null and skips persist when feature disabled","status":"passed","title":"returns null and skips persist when feature disabled","duration":0.8856999999999857,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant investigation state runtime adapter"],"fullName":"assistant investigation state runtime adapter builds snapshot and persists it when feature enabled","status":"passed","title":"builds snapshot and persists it when feature enabled","duration":3.653400000000005,"failureMessages":[],"meta":{}}],"startTime":1775902595351,"endTime":1775902595355.6533,"status":"passed","message":"","name":"X:/1C/NDC_1C/llm_normalizer/backend/tests/assistantInvestigationStateRuntimeAdapter.test.ts"},{"assertionResults":[{"ancestorTitles":["assistant lifecycle-aware answer mode v1"],"fullName":"assistant lifecycle-aware answer mode v1 promotes stage3 lifecycle mode when lifecycle answer flag is enabled","status":"passed","title":"promotes stage3 lifecycle mode when lifecycle answer flag is enabled","duration":22.1978,"failureMessages":[],"meta":{}}],"startTime":1775902594920,"endTime":1775902594942.1978,"status":"passed","message":"","name":"X:/1C/NDC_1C/llm_normalizer/backend/tests/assistantLifecycleAwareAnswerV1.test.ts"},{"assertionResults":[{"ancestorTitles":["assistant living chat attempt input builder"],"fullName":"assistant living chat attempt input builder builds living-chat runtime input with derived trace id and session scope","status":"passed","title":"builds living-chat runtime input with derived trace id and session scope","duration":2.321199999999976,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant living chat attempt input builder"],"fullName":"assistant living chat attempt input builder normalizes absent address runtime meta to null and preserves optional api key","status":"passed","title":"normalizes absent address runtime meta to null and preserves optional api key","duration":0.4129000000000076,"failureMessages":[],"meta":{}}],"startTime":1775902596199,"endTime":1775902596201.4128,"status":"passed","message":"","name":"X:/1C/NDC_1C/llm_normalizer/backend/tests/assistantLivingChatAttemptInputBuilder.test.ts"},{"assertionResults":[{"ancestorTitles":["assistant living chat attempt runtime adapter"],"fullName":"assistant living chat attempt runtime adapter wires llm runtime output into living handler execute callback","status":"passed","title":"wires llm runtime output into living handler execute callback","duration":2.728999999999985,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant living chat attempt runtime adapter"],"fullName":"assistant living chat attempt runtime adapter returns null when delegated handler returns null","status":"passed","title":"returns null when delegated handler returns null","duration":0.4072999999999922,"failureMessages":[],"meta":{}}],"startTime":1775902595666,"endTime":1775902595669.4072,"status":"passed","message":"","name":"X:/1C/NDC_1C/llm_normalizer/backend/tests/assistantLivingChatAttemptRuntimeAdapter.test.ts"},{"assertionResults":[{"ancestorTitles":["assistant living chat attempt runtime input builder"],"fullName":"assistant living chat attempt runtime input builder builds living-chat llm runtime input","status":"passed","title":"builds living-chat llm runtime input","duration":1.512900000000002,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant living chat attempt runtime input builder"],"fullName":"assistant living chat attempt runtime input builder builds living-chat handler runtime input with execute callback","status":"passed","title":"builds living-chat handler runtime input with execute callback","duration":0.9078000000000088,"failureMessages":[],"meta":{}}],"startTime":1775902595837,"endTime":1775902595839.9077,"status":"passed","message":"","name":"X:/1C/NDC_1C/llm_normalizer/backend/tests/assistantLivingChatAttemptRuntimeInputBuilder.test.ts"},{"assertionResults":[{"ancestorTitles":["assistant living chat handler runtime adapter"],"fullName":"assistant living chat handler runtime adapter returns finalized response when runtime is handled","status":"passed","title":"returns finalized response when runtime is handled","duration":3.941900000000004,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant living chat handler runtime adapter"],"fullName":"assistant living chat handler runtime adapter returns null when runtime is not handled","status":"passed","title":"returns null when runtime is not handled","duration":0.48910000000000764,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant living chat handler runtime adapter"],"fullName":"assistant living chat handler runtime adapter logs warn and returns null on runtime error","status":"passed","title":"logs warn and returns null on runtime error","duration":0.5157000000000096,"failureMessages":[],"meta":{}}],"startTime":1775902595533,"endTime":1775902595538.5156,"status":"passed","message":"","name":"X:/1C/NDC_1C/llm_normalizer/backend/tests/assistantLivingChatHandlerRuntimeAdapter.test.ts"},{"assertionResults":[{"ancestorTitles":["assistant living chat llm runtime adapter"],"fullName":"assistant living chat llm runtime adapter builds prompt/context internally and calls chat client with bounded output tokens","status":"passed","title":"builds prompt/context internally and calls chat client with bounded output tokens","duration":3.30510000000001,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant living chat llm runtime adapter"],"fullName":"assistant living chat llm runtime adapter uses defaults and fallback text when model output is empty","status":"passed","title":"uses defaults and fallback text when model output is empty","duration":0.4416999999999973,"failureMessages":[],"meta":{}}],"startTime":1775902595476,"endTime":1775902595479.4417,"status":"passed","message":"","name":"X:/1C/NDC_1C/llm_normalizer/backend/tests/assistantLivingChatLlmRuntimeAdapter.test.ts"},{"assertionResults":[{"ancestorTitles":["assistant living chat mode"],"fullName":"assistant living chat mode resolves active organization from slang mention using previously discovered organization list","status":"passed","title":"resolves active organization from slang mention using previously discovered organization list","duration":7.3271000000002005,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant living chat mode"],"fullName":"assistant living chat mode repairs mojibake user text before persisting conversation","status":"passed","title":"repairs mojibake user text before persisting conversation","duration":60.937799999999925,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant living chat mode"],"fullName":"assistant living chat mode does not treat organization fact lookup as scope-selection confirmation","status":"passed","title":"does not treat organization fact lookup as scope-selection confirmation","duration":10.271799999999985,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant living chat mode"],"fullName":"assistant living chat mode keeps organization fact follow-up in deterministic boundary mode on short confirmation","status":"passed","title":"keeps organization fact follow-up in deterministic boundary mode on short confirmation","duration":3.901700000000119,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant living chat mode"],"fullName":"assistant living chat mode handles casual greeting in chat mode without deep-pipeline pass","status":"passed","title":"handles casual greeting in chat mode without deep-pipeline pass","duration":12.29119999999989,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant living chat mode"],"fullName":"assistant living chat mode does not force address lane for unsupported low-confidence predecompose canonical","status":"passed","title":"does not force address lane for unsupported low-confidence predecompose canonical","duration":2.9534000000001015,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant living chat mode"],"fullName":"assistant living chat mode keeps casual 'че как' in chat mode when predecompose canonical is unsupported","status":"passed","title":"keeps casual 'че как' in chat mode when predecompose canonical is unsupported","duration":5.186099999999897,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant living chat mode"],"fullName":"assistant living chat mode returns capability contract and avoids address lane for 'и 1с можешь настроить?'","status":"passed","title":"returns capability contract and avoids address lane for 'и 1с можешь настроить?'","duration":3.7899999999999636,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant living chat mode"],"fullName":"assistant living chat mode returns operational boundary reply for imperative setup request and avoids address lane","status":"passed","title":"returns operational boundary reply for imperative setup request and avoids address lane","duration":3.2281000000000404,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant living chat mode"],"fullName":"assistant living chat mode returns safety refusal for destructive request under coercion and avoids address lane","status":"passed","title":"returns safety refusal for destructive request under coercion and avoids address lane","duration":4.928100000000086,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant living chat mode"],"fullName":"assistant living chat mode strips unexpected CJK fragments from live chat reply when user did not request CJK","status":"passed","title":"strips unexpected CJK fragments from live chat reply when user did not request CJK","duration":2.90319999999997,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant living chat mode"],"fullName":"assistant living chat mode handles mojibake capability query and avoids address clarification flow","status":"passed","title":"handles mojibake capability query and avoids address clarification flow","duration":2.4700000000000273,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant living chat mode"],"fullName":"assistant living chat mode handles mojibake feature-capability wording and avoids free-form llm chat","status":"passed","title":"handles mojibake feature-capability wording and avoids free-form llm chat","duration":3.9318000000000666,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant living chat mode"],"fullName":"assistant living chat mode handles data-scope meta question as deterministic chat contract","status":"passed","title":"handles data-scope meta question as deterministic chat contract","duration":5.564599999999928,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant living chat mode"],"fullName":"assistant living chat mode handles 'какая база подрублена?' as deterministic data-scope contract","status":"passed","title":"handles 'какая база подрублена?' as deterministic data-scope contract","duration":2.7198000000000775,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant living chat mode"],"fullName":"assistant living chat mode handles typo data-scope query with misspelled company token as deterministic contract","status":"passed","title":"handles typo data-scope query with misspelled company token as deterministic contract","duration":2.8411999999998443,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant living chat mode"],"fullName":"assistant living chat mode handles no-question-mark data-scope phrase with interrogative token as deterministic contract","status":"passed","title":"handles no-question-mark data-scope phrase with interrogative token as deterministic contract","duration":17.291200000000117,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant living chat mode"],"fullName":"assistant living chat mode does not misroute contract ranking query to data-scope when canonical text contains 'компании'","status":"passed","title":"does not misroute contract ranking query to data-scope when canonical text contains 'компании'","duration":5.996800000000121,"failureMessages":[],"meta":{}}],"startTime":1775902594530,"endTime":1775902594688.9968,"status":"passed","message":"","name":"X:/1C/NDC_1C/llm_normalizer/backend/tests/assistantLivingChatMode.test.ts"},{"assertionResults":[{"ancestorTitles":["assistant living chat runtime adapter"],"fullName":"assistant living chat runtime adapter selects deterministic data scope branch and enriches organization context","status":"passed","title":"selects deterministic data scope branch and enriches organization context","duration":1.5813999999999737,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant living chat runtime adapter"],"fullName":"assistant living chat runtime adapter selects safety refusal branch for dangerous capability meta query","status":"passed","title":"selects safety refusal branch for dangerous capability meta query","duration":0.45060000000000855,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant living chat runtime adapter"],"fullName":"assistant living chat runtime adapter runs llm branch and applies script + grounding guards in order","status":"passed","title":"runs llm branch and applies script + grounding guards in order","duration":0.405399999999986,"failureMessages":[],"meta":{}}],"startTime":1775902595659,"endTime":1775902595661.4507,"status":"passed","message":"","name":"X:/1C/NDC_1C/llm_normalizer/backend/tests/assistantLivingChatRuntimeAdapter.test.ts"},{"assertionResults":[{"ancestorTitles":["assistant living chat turn finalize runtime adapter"],"fullName":"assistant living chat turn finalize runtime adapter builds assistant chat item and emits expected living chat log envelope","status":"passed","title":"builds assistant chat item and emits expected living chat log envelope","duration":1.3339999999999748,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant living chat turn finalize runtime adapter"],"fullName":"assistant living chat turn finalize runtime adapter uses default commit runtime and returns persisted conversation","status":"passed","title":"uses default commit runtime and returns persisted conversation","duration":0.7606000000000108,"failureMessages":[],"meta":{}}],"startTime":1775902595665,"endTime":1775902595666.7605,"status":"passed","message":"","name":"X:/1C/NDC_1C/llm_normalizer/backend/tests/assistantLivingChatTurnFinalizeRuntimeAdapter.test.ts"},{"assertionResults":[{"ancestorTitles":["assistant living router mode decision"],"fullName":"assistant living router mode decision returns address_data when address lane already triggered","status":"passed","title":"returns address_data when address lane already triggered","duration":0.9010999999999854,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant living router mode decision"],"fullName":"assistant living router mode decision keeps deep pipeline in mock mode to avoid test-env network calls","status":"passed","title":"keeps deep pipeline in mock mode to avoid test-env network calls","duration":0.17719999999997071,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant living router mode decision"],"fullName":"assistant living router mode decision routes casual non-data phrase to chat mode","status":"passed","title":"routes casual non-data phrase to chat mode","duration":2.713799999999992,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant living router mode decision"],"fullName":"assistant living router mode decision keeps deep mode for strong data signal","status":"passed","title":"keeps deep mode for strong data signal","duration":0.2939000000000078,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant living router mode decision"],"fullName":"assistant living router mode decision routes capability question to chat even when phrase contains 1С","status":"passed","title":"routes capability question to chat even when phrase contains 1С","duration":0.14859999999998763,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant living router mode decision"],"fullName":"assistant living router mode decision routes capability question 'ok - what can you do in 1c' to chat","status":"passed","title":"routes capability question 'ok - what can you do in 1c' to chat","duration":0.12999999999999545,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant living router mode decision"],"fullName":"assistant living router mode decision routes feature-capability wording to chat","status":"passed","title":"routes feature-capability wording to chat","duration":0.09309999999999263,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant living router mode decision"],"fullName":"assistant living router mode decision routes data-scope question to chat instead of address lane","status":"passed","title":"routes data-scope question to chat instead of address lane","duration":0.6259000000000015,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant living router mode decision"],"fullName":"assistant living router mode decision routes 'whose base is this' style question to chat","status":"passed","title":"routes 'whose base is this' style question to chat","duration":0.46479999999996835,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant living router mode decision"],"fullName":"assistant living router mode decision routes 'какая база подрублена?' to data-scope chat mode","status":"passed","title":"routes 'какая база подрублена?' to data-scope chat mode","duration":0.10669999999998936,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant living router mode decision"],"fullName":"assistant living router mode decision routes typo data-scope wording with misspelled company token to chat","status":"passed","title":"routes typo data-scope wording with misspelled company token to chat","duration":0.09029999999995653,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant living router mode decision"],"fullName":"assistant living router mode decision routes data-scope wording without question mark when interrogative token is present","status":"passed","title":"routes data-scope wording without question mark when interrogative token is present","duration":0.05900000000002592,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant living router mode decision"],"fullName":"assistant living router mode decision does not treat contract ranking data query as data-scope meta question","status":"passed","title":"does not treat contract ranking data query as data-scope meta question","duration":0.08859999999998536,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant orchestration contract"],"fullName":"assistant orchestration contract keeps VAT payable forecast query in address lane","status":"passed","title":"keeps VAT payable forecast query in address lane","duration":9.20580000000001,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant orchestration contract"],"fullName":"assistant orchestration contract keeps supported contract analytics query in address lane","status":"passed","title":"keeps supported contract analytics query in address lane","duration":9.033400000000029,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant orchestration contract"],"fullName":"assistant orchestration contract keeps VAT explain follow-up in address lane when followup context is present","status":"passed","title":"keeps VAT explain follow-up in address lane when followup context is present","duration":8.916499999999985,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant orchestration contract"],"fullName":"assistant orchestration contract keeps explicit address-mode unknown-intent data query in address lane","status":"passed","title":"keeps explicit address-mode unknown-intent data query in address lane","duration":2.0230000000000246,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant orchestration contract"],"fullName":"assistant orchestration contract does not force address lane for deep-analysis unknown intent query with date-like token","status":"passed","title":"does not force address lane for deep-analysis unknown intent query with date-like token","duration":1.3707999999999743,"failureMessages":[],"meta":{}}],"startTime":1775902595057,"endTime":1775902595093.3708,"status":"passed","message":"","name":"X:/1C/NDC_1C/llm_normalizer/backend/tests/assistantLivingRouter.test.ts"},{"assertionResults":[{"ancestorTitles":["assistant MCP runtime bridge"],"fullName":"assistant MCP runtime bridge does not call MCP when runtime flag is disabled","status":"passed","title":"does not call MCP when runtime flag is disabled","duration":55.51220000000001,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant MCP runtime bridge"],"fullName":"assistant MCP runtime bridge uses MCP live probe for hybrid route when runtime flag is enabled","status":"passed","title":"uses MCP live probe for hybrid route when runtime flag is enabled","duration":24.2962,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant MCP runtime bridge"],"fullName":"assistant MCP runtime bridge keeps snapshot fallback when MCP responds with error","status":"passed","title":"keeps snapshot fallback when MCP responds with error","duration":12.952600000000018,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant MCP runtime bridge"],"fullName":"assistant MCP runtime bridge does not inject out-of-scope rows when account filter matched zero","status":"passed","title":"does not inject out-of-scope rows when account filter matched zero","duration":26.340100000000007,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant MCP runtime bridge"],"fullName":"assistant MCP runtime bridge uses claim-bound live call sequence for RBP lifecycle query","status":"passed","title":"uses claim-bound live call sequence for RBP lifecycle query","duration":22.893799999999942,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant MCP runtime bridge"],"fullName":"assistant MCP runtime bridge uses claim-bound live call sequence for fixed-asset amortization coverage query","status":"passed","title":"uses claim-bound live call sequence for fixed-asset amortization coverage query","duration":13.267799999999966,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant MCP runtime bridge"],"fullName":"assistant MCP runtime bridge uses claim-bound VAT live path instead of supplier-tail generic probe for VAT chain query","status":"passed","title":"uses claim-bound VAT live path instead of supplier-tail generic probe for VAT chain query","duration":20.69900000000007,"failureMessages":[],"meta":{}}],"startTime":1775902593860,"endTime":1775902594036.699,"status":"passed","message":"","name":"X:/1C/NDC_1C/llm_normalizer/backend/tests/assistantMcpRuntimeBridge.test.ts"},{"assertionResults":[{"ancestorTitles":["assistant message log assembler"],"fullName":"assistant message log assembler builds deep analysis log details and resolves full coverage status","status":"passed","title":"builds deep analysis log details and resolves full coverage status","duration":2.3319999999999936,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant message log assembler"],"fullName":"assistant message log assembler marks partial coverage and omits optional sections when empty","status":"passed","title":"marks partial coverage and omits optional sections when empty","duration":0.279200000000003,"failureMessages":[],"meta":{}}],"startTime":1775902595900,"endTime":1775902595902.332,"status":"passed","message":"","name":"X:/1C/NDC_1C/llm_normalizer/backend/tests/assistantMessageLogAssembler.test.ts"},{"assertionResults":[{"ancestorTitles":["assistant orchestration contracts v1"],"fullName":"assistant orchestration contracts v1 builds query frame and execution plan contracts with normalized analysis context","status":"passed","title":"builds query frame and execution plan contracts with normalized analysis context","duration":1.93780000000001,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant orchestration contracts v1"],"fullName":"assistant orchestration contracts v1 classifies fully answered and misrouted outcomes","status":"passed","title":"classifies fully answered and misrouted outcomes","duration":0.4444999999999766,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant orchestration contracts v1"],"fullName":"assistant orchestration contracts v1 classifies tooling and entity-binding failures","status":"passed","title":"classifies tooling and entity-binding failures","duration":0.1670000000000016,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant orchestration contracts v1"],"fullName":"assistant orchestration contracts v1 builds evidence bundle and coverage contracts","status":"passed","title":"builds evidence bundle and coverage contracts","duration":0.3581000000000074,"failureMessages":[],"meta":{}}],"startTime":1775902595900,"endTime":1775902595903.3582,"status":"passed","message":"","name":"X:/1C/NDC_1C/llm_normalizer/backend/tests/assistantOrchestrationContracts.test.ts"},{"assertionResults":[{"ancestorTitles":["assistant orchestration runtime adapter"],"fullName":"assistant orchestration runtime adapter runs requirement -> coverage -> grounding pipeline in order","status":"passed","title":"runs requirement -> coverage -> grounding pipeline in order","duration":1.3404000000000167,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant orchestration runtime adapter"],"fullName":"assistant orchestration runtime adapter reuses precomputed requirement extraction when provided","status":"passed","title":"reuses precomputed requirement extraction when provided","duration":0.8688999999999965,"failureMessages":[],"meta":{}}],"startTime":1775902595722,"endTime":1775902595723.869,"status":"passed","message":"","name":"X:/1C/NDC_1C/llm_normalizer/backend/tests/assistantOrchestrationRuntimeAdapter.test.ts"},{"assertionResults":[{"ancestorTitles":["assistant organization scope runtime adapter"],"fullName":"assistant organization scope runtime adapter resolves selected organization from user message and promotes it to active scope","status":"passed","title":"resolves selected organization from user message and promotes it to active scope","duration":1.8954999999999984,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant organization scope runtime adapter"],"fullName":"assistant organization scope runtime adapter falls back active organization to last assistant scope when selection is absent","status":"passed","title":"falls back active organization to last assistant scope when selection is absent","duration":0.686099999999982,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant organization scope runtime adapter"],"fullName":"assistant organization scope runtime adapter merges organization into followup previous filters when organization is missing","status":"passed","title":"merges organization into followup previous filters when organization is missing","duration":0.18719999999999004,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant organization scope runtime adapter"],"fullName":"assistant organization scope runtime adapter keeps existing organization in followup filters and returns null for empty context without org","status":"passed","title":"keeps existing organization in followup filters and returns null for empty context without org","duration":0.1671000000000049,"failureMessages":[],"meta":{}}],"startTime":1775902595837,"endTime":1775902595840.1873,"status":"passed","message":"","name":"X:/1C/NDC_1C/llm_normalizer/backend/tests/assistantOrganizationScopeRuntimeAdapter.test.ts"},{"assertionResults":[{"ancestorTitles":["assistant outgoing encoding repair"],"fullName":"assistant outgoing encoding repair repairs mojibake in address-lane replies before returning to user","status":"passed","title":"repairs mojibake in address-lane replies before returning to user","duration":64.7869,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant outgoing encoding repair"],"fullName":"assistant outgoing encoding repair repairs mojibake in living-chat LLM replies before script guard","status":"passed","title":"repairs mojibake in living-chat LLM replies before script guard","duration":17.23580000000004,"failureMessages":[],"meta":{}}],"startTime":1775902594528,"endTime":1775902594609.2358,"status":"passed","message":"","name":"X:/1C/NDC_1C/llm_normalizer/backend/tests/assistantOutgoingEncodingRepair.test.ts"},{"assertionResults":[{"ancestorTitles":["assistant P0 eval harness (Wave 7)"],"fullName":"assistant P0 eval harness (Wave 7) runs assistant_p0 eval and returns formal product metrics + verdict","status":"failed","title":"runs assistant_p0 eval and returns formal product metrics + verdict","duration":5026.7389,"failureMessages":["Error: STACK_TRACE_ERROR\n at task (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:638:27)\n at Object. (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:662:16)\n at Object. (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:458:28)\n at chain (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:369:14)\n at X:\\1C\\NDC_1C\\llm_normalizer\\backend\\tests\\assistantP0EvalHarness.test.ts:53:3\n at file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:734:40\n at runWithSuite (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1849:8)\n at Object.collect (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:734:10)\n at Object.collect (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:738:54)\n at processTicksAndRejections (node:internal/process/task_queues:105:5)\n at collectTests (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1179:25)\n at startTests (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1817:17)\n at file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/vitest/dist/chunks/runBaseTests.9Ij9_de-.js:117:26\n at withEnv (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/vitest/dist/chunks/runBaseTests.9Ij9_de-.js:84:3)\n at run (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/vitest/dist/chunks/runBaseTests.9Ij9_de-.js:109:2)"],"meta":{}},{"ancestorTitles":["assistant P0 eval harness (Wave 7)"],"fullName":"assistant P0 eval harness (Wave 7) loads formal P0 corpus split for 3 domains","status":"passed","title":"loads formal P0 corpus split for 3 domains","duration":195.98449999999957,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant P0 eval harness (Wave 7)"],"fullName":"assistant P0 eval harness (Wave 7) supports Wave 9 expanded corpus classes and follow-up context metrics","status":"passed","title":"supports Wave 9 expanded corpus classes and follow-up context metrics","duration":231.3168000000005,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant P0 eval harness (Wave 7)"],"fullName":"assistant P0 eval harness (Wave 7) builds before/after comparison and returns formal verdict delta","status":"failed","title":"builds before/after comparison and returns formal verdict delta","duration":5012.3256,"failureMessages":["Error: STACK_TRACE_ERROR\n at task (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:638:27)\n at Object. (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:662:16)\n at Object. (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:458:28)\n at chain (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:369:14)\n at X:\\1C\\NDC_1C\\llm_normalizer\\backend\\tests\\assistantP0EvalHarness.test.ts:161:3\n at file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:734:40\n at runWithSuite (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1849:8)\n at Object.collect (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:734:10)\n at Object.collect (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:738:54)\n at processTicksAndRejections (node:internal/process/task_queues:105:5)\n at collectTests (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1179:25)\n at startTests (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1817:17)\n at file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/vitest/dist/chunks/runBaseTests.9Ij9_de-.js:117:26\n at withEnv (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/vitest/dist/chunks/runBaseTests.9Ij9_de-.js:84:3)\n at run (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/vitest/dist/chunks/runBaseTests.9Ij9_de-.js:109:2)"],"meta":{}},{"ancestorTitles":["assistant P0 eval harness (Wave 7)"],"fullName":"assistant P0 eval harness (Wave 7) respects P0 eval feature gate via Stage2 eval flag OFF/ON","status":"passed","title":"respects P0 eval feature gate via Stage2 eval flag OFF/ON","duration":216.22539999999935,"failureMessages":[],"meta":{}}],"startTime":1775902593732,"endTime":1775902604416.2253,"status":"failed","message":"","name":"X:/1C/NDC_1C/llm_normalizer/backend/tests/assistantP0EvalHarness.test.ts"},{"assertionResults":[{"ancestorTitles":["assistant problem-centric answer mode v1"],"fullName":"assistant problem-centric answer mode v1 uses problem-centric answer mode on problem-heavy case when flag is ON","status":"passed","title":"uses problem-centric answer mode on problem-heavy case when flag is ON","duration":25.490399999999994,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant problem-centric answer mode v1"],"fullName":"assistant problem-centric answer mode v1 falls back to Stage 1 path for the same case when problem-centric flag is OFF","status":"passed","title":"falls back to Stage 1 path for the same case when problem-centric flag is OFF","duration":8.028999999999996,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant problem-centric answer mode v1"],"fullName":"assistant problem-centric answer mode v1 keeps focused grounded case on Stage 1 path even when problem-centric flag is ON","status":"passed","title":"keeps focused grounded case on Stage 1 path even when problem-centric flag is ON","duration":2.5516999999999825,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant problem-centric answer mode v1"],"fullName":"assistant problem-centric answer mode v1 enables problem-centric mode on mixed focused case when weak mechanism signals are present","status":"passed","title":"enables problem-centric mode on mixed focused case when weak mechanism signals are present","duration":1.9382999999999981,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant problem-centric answer mode v1"],"fullName":"assistant problem-centric answer mode v1 does not expose raw technical refs in primary problem-centric text","status":"passed","title":"does not expose raw technical refs in primary problem-centric text","duration":3.1928000000000054,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant problem-centric answer mode v1"],"fullName":"assistant problem-centric answer mode v1 produces limited answer for weak problem units without false overclaim","status":"passed","title":"produces limited answer for weak problem units without false overclaim","duration":3.1122000000000014,"failureMessages":[],"meta":{}}],"startTime":1775902594787,"endTime":1775902594832.1123,"status":"passed","message":"","name":"X:/1C/NDC_1C/llm_normalizer/backend/tests/assistantProblemCentricAnswerV1.test.ts"},{"assertionResults":[{"ancestorTitles":["assistant problem-unit continuity state"],"fullName":"assistant problem-unit continuity state stores bounded problem_unit_state in investigation snapshot and session state","status":"failed","title":"stores bounded problem_unit_state in investigation snapshot and session state","duration":5015.7169,"failureMessages":["Error: STACK_TRACE_ERROR\n at task (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:638:27)\n at Object. (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:662:16)\n at Object. (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:458:28)\n at chain (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:369:14)\n at X:\\1C\\NDC_1C\\llm_normalizer\\backend\\tests\\assistantProblemUnitContinuityState.test.ts:48:3\n at file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:734:40\n at runWithSuite (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1849:8)\n at Object.collect (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:734:10)\n at Object.collect (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:738:54)\n at processTicksAndRejections (node:internal/process/task_queues:105:5)\n at collectTests (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1179:25)\n at startTests (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1817:17)\n at file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/vitest/dist/chunks/runBaseTests.9Ij9_de-.js:117:26\n at withEnv (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/vitest/dist/chunks/runBaseTests.9Ij9_de-.js:84:3)\n at run (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/vitest/dist/chunks/runBaseTests.9Ij9_de-.js:109:2)"],"meta":{}}],"startTime":1775902593866,"endTime":1775902598881.7168,"status":"failed","message":"","name":"X:/1C/NDC_1C/llm_normalizer/backend/tests/assistantProblemUnitContinuityState.test.ts"},{"assertionResults":[{"ancestorTitles":["assistant problem-unit runtime rollout"],"fullName":"assistant problem-unit runtime rollout emits problem-unit layer on problem-heavy scenarios when flag is ON","status":"failed","title":"emits problem-unit layer on problem-heavy scenarios when flag is ON","duration":1030.001,"failureMessages":["AssertionError: expected 0 to be greater than 0\n at X:\\1C\\NDC_1C\\llm_normalizer\\backend\\tests\\assistantProblemUnitRuntimeRollout.test.ts:83:29\n at processTicksAndRejections (node:internal/process/task_queues:105:5)\n at file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:752:20"],"meta":{}},{"ancestorTitles":["assistant problem-unit runtime rollout"],"fullName":"assistant problem-unit runtime rollout does not emit problem-unit layer when flag is OFF","status":"failed","title":"does not emit problem-unit layer when flag is OFF","duration":5013.53,"failureMessages":["Error: STACK_TRACE_ERROR\n at task (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:638:27)\n at Object. (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:662:16)\n at Object. (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:458:28)\n at chain (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:369:14)\n at X:\\1C\\NDC_1C\\llm_normalizer\\backend\\tests\\assistantProblemUnitRuntimeRollout.test.ts:129:3\n at file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:734:40\n at runWithSuite (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1849:8)\n at Object.collect (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:734:10)\n at Object.collect (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:738:54)\n at processTicksAndRejections (node:internal/process/task_queues:105:5)\n at collectTests (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1179:25)\n at startTests (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1817:17)\n at file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/vitest/dist/chunks/runBaseTests.9Ij9_de-.js:117:26\n at withEnv (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/vitest/dist/chunks/runBaseTests.9Ij9_de-.js:84:3)\n at run (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/vitest/dist/chunks/runBaseTests.9Ij9_de-.js:109:2)"],"meta":{}}],"startTime":1775902593730,"endTime":1775902599773.53,"status":"failed","message":"","name":"X:/1C/NDC_1C/llm_normalizer/backend/tests/assistantProblemUnitRuntimeRollout.test.ts"},{"assertionResults":[{"ancestorTitles":["assistant query planning module"],"fullName":"assistant query planning module builds fragment text map with account hints enrichment","status":"passed","title":"builds fragment text map with account hints enrichment","duration":0.8473999999999933,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant query planning module"],"fullName":"assistant query planning module builds deterministic execution plan from route summary","status":"passed","title":"builds deterministic execution plan from route summary","duration":1.1773000000000025,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant query planning module"],"fullName":"assistant query planning module builds legacy debug routes via resolver","status":"passed","title":"builds legacy debug routes via resolver","duration":0.2261000000000024,"failureMessages":[],"meta":{}}],"startTime":1775902595665,"endTime":1775902595667.226,"status":"passed","message":"","name":"X:/1C/NDC_1C/llm_normalizer/backend/tests/assistantQueryPlanning.test.ts"},{"assertionResults":[{"ancestorTitles":["stage4 blocker-pack runtime guards"],"fullName":"stage4 blocker-pack runtime guards flags temporal anchor drift outside July 2020 snapshot","status":"passed","title":"flags temporal anchor drift outside July 2020 snapshot","duration":3.304899999999975,"failureMessages":[],"meta":{}},{"ancestorTitles":["stage4 blocker-pack runtime guards"],"fullName":"stage4 blocker-pack runtime guards locks July month window when question has month-only anchor","status":"passed","title":"locks July month window when question has month-only anchor","duration":1.1800999999999249,"failureMessages":[],"meta":{}},{"ancestorTitles":["stage4 blocker-pack runtime guards"],"fullName":"stage4 blocker-pack runtime guards filters customer settlement semantics from supplier/payable case","status":"failed","title":"filters customer settlement semantics from supplier/payable case","duration":10.168800000000033,"failureMessages":["AssertionError: expected 'mixed_or_unresolved' to be 'supplier_payable' // Object.is equality\n at X:\\1C\\NDC_1C\\llm_normalizer\\backend\\tests\\assistantRuntimeGuardsStage4Pack.test.ts:237:28\n at file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:155:11\n at file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:752:26\n at file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1897:20\n at new Promise ()\n at runWithTimeout (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1863:10)\n at runTest (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1574:12)\n at processTicksAndRejections (node:internal/process/task_queues:105:5)\n at runSuite (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1729:8)\n at runSuite (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1729:8)"],"meta":{}},{"ancestorTitles":["stage4 blocker-pack runtime guards"],"fullName":"stage4 blocker-pack runtime guards resolves supplier polarity with dominant 60-account signals despite weak customer noise","status":"passed","title":"resolves supplier polarity with dominant 60-account signals despite weak customer noise","duration":1.6304999999999836,"failureMessages":[],"meta":{}},{"ancestorTitles":["stage4 blocker-pack runtime guards"],"fullName":"stage4 blocker-pack runtime guards cleans polluted account anchors from date/amount numerics","status":"passed","title":"cleans polluted account anchors from date/amount numerics","duration":1.3999000000000024,"failureMessages":[],"meta":{}},{"ancestorTitles":["stage4 blocker-pack runtime guards"],"fullName":"stage4 blocker-pack runtime guards rejects inadmissible live evidence on zero matched_rows and wrong account/date","status":"passed","title":"rejects inadmissible live evidence on zero matched_rows and wrong account/date","duration":3.423000000000002,"failureMessages":[],"meta":{}},{"ancestorTitles":["stage4 blocker-pack runtime guards"],"fullName":"stage4 blocker-pack runtime guards degrades grounded status when eligibility guard fails","status":"failed","title":"degrades grounded status when eligibility guard fails","duration":3.170600000000036,"failureMessages":["AssertionError: expected 'Запрошенный период выходит за доступн…' to match /Недостаточно РґРѕРїСѓСЃС…/i\n at X:\\1C\\NDC_1C\\llm_normalizer\\backend\\tests\\assistantRuntimeGuardsStage4Pack.test.ts:424:40\n at file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:155:11\n at file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:752:26\n at file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1897:20\n at new Promise ()\n at runWithTimeout (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1863:10)\n at runTest (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1574:12)\n at processTicksAndRejections (node:internal/process/task_queues:105:5)\n at runSuite (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1729:8)\n at runSuite (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1729:8)"],"meta":{}},{"ancestorTitles":["stage4 blocker-pack runtime guards"],"fullName":"stage4 blocker-pack runtime guards reconstructs fixed-asset expected vs actual coverage in claim-bound targeting","status":"passed","title":"reconstructs fixed-asset expected vs actual coverage in claim-bound targeting","duration":6.638000000000034,"failureMessages":[],"meta":{}},{"ancestorTitles":["stage4 blocker-pack runtime guards"],"fullName":"stage4 blocker-pack runtime guards does not misclassify settlement 62.02 question into VAT or FA claim paths","status":"passed","title":"does not misclassify settlement 62.02 question into VAT or FA claim paths","duration":1.313600000000065,"failureMessages":[],"meta":{}},{"ancestorTitles":["stage4 blocker-pack runtime guards"],"fullName":"stage4 blocker-pack runtime guards keeps VAT priority over supplier wording in shared domain inference","status":"passed","title":"keeps VAT priority over supplier wording in shared domain inference","duration":1.9667000000000598,"failureMessages":[],"meta":{}}],"startTime":1775902593926,"endTime":1775902593959.9668,"status":"failed","message":"","name":"X:/1C/NDC_1C/llm_normalizer/backend/tests/assistantRuntimeGuardsStage4Pack.test.ts"},{"assertionResults":[{"ancestorTitles":["assistant stage2 duplicate collapse probe suite"],"fullName":"assistant stage2 duplicate collapse probe suite loads supplemental probe suite and confirms duplicate collapse signal","status":"passed","title":"loads supplemental probe suite and confirms duplicate collapse signal","duration":4.161599999999993,"failureMessages":[],"meta":{}}],"startTime":1775902595397,"endTime":1775902595401.1616,"status":"passed","message":"","name":"X:/1C/NDC_1C/llm_normalizer/backend/tests/assistantStage2DuplicateCollapseProbe.test.ts"},{"assertionResults":[{"ancestorTitles":["assistant Stage 2 eval harness"],"fullName":"assistant Stage 2 eval harness runs assistant_stage2 harness and returns Stage 2 raw metrics + rubric bands","status":"failed","title":"runs assistant_stage2 harness and returns Stage 2 raw metrics + rubric bands","duration":5028.2522,"failureMessages":["Error: STACK_TRACE_ERROR\n at task (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:638:27)\n at Object. (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:662:16)\n at Object. (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:458:28)\n at chain (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:369:14)\n at X:\\1C\\NDC_1C\\llm_normalizer\\backend\\tests\\assistantStage2EvalHarness.test.ts:62:3\n at file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:734:40\n at runWithSuite (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1849:8)\n at Object.collect (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:734:10)\n at Object.collect (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:738:54)\n at processTicksAndRejections (node:internal/process/task_queues:105:5)\n at collectTests (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1179:25)\n at startTests (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1817:17)\n at file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/vitest/dist/chunks/runBaseTests.9Ij9_de-.js:117:26\n at withEnv (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/vitest/dist/chunks/runBaseTests.9Ij9_de-.js:84:3)\n at run (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/vitest/dist/chunks/runBaseTests.9Ij9_de-.js:109:2)"],"meta":{}},{"ancestorTitles":["assistant Stage 2 eval harness"],"fullName":"assistant Stage 2 eval harness loads Stage 2 canonical suite metadata and keeps it stable","status":"failed","title":"loads Stage 2 canonical suite metadata and keeps it stable","duration":5003.0019999999995,"failureMessages":["Error: STACK_TRACE_ERROR\n at task (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:638:27)\n at Object. (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:662:16)\n at Object. (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:458:28)\n at chain (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:369:14)\n at X:\\1C\\NDC_1C\\llm_normalizer\\backend\\tests\\assistantStage2EvalHarness.test.ts:103:3\n at file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:734:40\n at runWithSuite (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1849:8)\n at Object.collect (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:734:10)\n at Object.collect (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:738:54)\n at processTicksAndRejections (node:internal/process/task_queues:105:5)\n at collectTests (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1179:25)\n at startTests (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1817:17)\n at file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/vitest/dist/chunks/runBaseTests.9Ij9_de-.js:117:26\n at withEnv (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/vitest/dist/chunks/runBaseTests.9Ij9_de-.js:84:3)\n at run (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/vitest/dist/chunks/runBaseTests.9Ij9_de-.js:109:2)"],"meta":{}},{"ancestorTitles":["assistant Stage 2 eval harness"],"fullName":"assistant Stage 2 eval harness handles follow-up subset and keeps subset denominator explicit","status":"failed","title":"handles follow-up subset and keeps subset denominator explicit","duration":5001.1746,"failureMessages":["Error: STACK_TRACE_ERROR\n at task (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:638:27)\n at Object. (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:662:16)\n at Object. (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:458:28)\n at chain (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:369:14)\n at X:\\1C\\NDC_1C\\llm_normalizer\\backend\\tests\\assistantStage2EvalHarness.test.ts:130:3\n at file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:734:40\n at runWithSuite (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1849:8)\n at Object.collect (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:734:10)\n at Object.collect (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:738:54)\n at processTicksAndRejections (node:internal/process/task_queues:105:5)\n at collectTests (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1179:25)\n at startTests (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1817:17)\n at file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/vitest/dist/chunks/runBaseTests.9Ij9_de-.js:117:26\n at withEnv (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/vitest/dist/chunks/runBaseTests.9Ij9_de-.js:84:3)\n at run (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/vitest/dist/chunks/runBaseTests.9Ij9_de-.js:109:2)"],"meta":{}},{"ancestorTitles":["assistant Stage 2 eval harness"],"fullName":"assistant Stage 2 eval harness builds Stage 2 comparison artifact from baseline and current runs","status":"failed","title":"builds Stage 2 comparison artifact from baseline and current runs","duration":5012.191699999999,"failureMessages":["Error: STACK_TRACE_ERROR\n at task (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:638:27)\n at Object. (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:662:16)\n at Object. (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:458:28)\n at chain (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:369:14)\n at X:\\1C\\NDC_1C\\llm_normalizer\\backend\\tests\\assistantStage2EvalHarness.test.ts:155:3\n at file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:734:40\n at runWithSuite (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1849:8)\n at Object.collect (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:734:10)\n at Object.collect (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:738:54)\n at processTicksAndRejections (node:internal/process/task_queues:105:5)\n at collectTests (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1179:25)\n at startTests (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1817:17)\n at file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/vitest/dist/chunks/runBaseTests.9Ij9_de-.js:117:26\n at withEnv (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/vitest/dist/chunks/runBaseTests.9Ij9_de-.js:84:3)\n at run (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/vitest/dist/chunks/runBaseTests.9Ij9_de-.js:109:2)"],"meta":{}},{"ancestorTitles":["assistant Stage 2 eval harness"],"fullName":"assistant Stage 2 eval harness keeps legacy eval path unchanged by default","status":"passed","title":"keeps legacy eval path unchanged by default","duration":128.76970000000074,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant Stage 2 eval harness"],"fullName":"assistant Stage 2 eval harness respects Stage 2 eval feature flag OFF/ON","status":"failed","title":"respects Stage 2 eval feature flag OFF/ON","duration":5018.0658,"failureMessages":["Error: STACK_TRACE_ERROR\n at task (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:638:27)\n at Object. (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:662:16)\n at Object. (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:458:28)\n at chain (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:369:14)\n at X:\\1C\\NDC_1C\\llm_normalizer\\backend\\tests\\assistantStage2EvalHarness.test.ts:223:3\n at file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:734:40\n at runWithSuite (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1849:8)\n at Object.collect (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:734:10)\n at Object.collect (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:738:54)\n at processTicksAndRejections (node:internal/process/task_queues:105:5)\n at collectTests (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1179:25)\n at startTests (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1817:17)\n at file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/vitest/dist/chunks/runBaseTests.9Ij9_de-.js:117:26\n at withEnv (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/vitest/dist/chunks/runBaseTests.9Ij9_de-.js:84:3)\n at run (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/vitest/dist/chunks/runBaseTests.9Ij9_de-.js:109:2)"],"meta":{}}],"startTime":1775902593730,"endTime":1775902618922.066,"status":"failed","message":"","name":"X:/1C/NDC_1C/llm_normalizer/backend/tests/assistantStage2EvalHarness.test.ts"},{"assertionResults":[{"ancestorTitles":["assistant stage3 lifecycle acceptance probe suite"],"fullName":"assistant stage3 lifecycle acceptance probe suite runs stage3 lifecycle probe prompts with separate acceptance checks","status":"failed","title":"runs stage3 lifecycle probe prompts with separate acceptance checks","duration":5014.6967,"failureMessages":["Error: STACK_TRACE_ERROR\n at task (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:638:27)\n at Object. (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:662:16)\n at Object. (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:458:28)\n at chain (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:369:14)\n at X:\\1C\\NDC_1C\\llm_normalizer\\backend\\tests\\assistantStage3LifecycleAcceptanceProbe.test.ts:109:3\n at file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:734:40\n at runWithSuite (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1849:8)\n at Object.collect (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:734:10)\n at Object.collect (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:738:54)\n at processTicksAndRejections (node:internal/process/task_queues:105:5)\n at collectTests (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1179:25)\n at startTests (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/@vitest/runner/dist/chunk-hooks.js:1817:17)\n at file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/vitest/dist/chunks/runBaseTests.9Ij9_de-.js:117:26\n at withEnv (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/vitest/dist/chunks/runBaseTests.9Ij9_de-.js:84:3)\n at run (file:///X:/1C/NDC_1C/llm_normalizer/backend/node_modules/vitest/dist/chunks/runBaseTests.9Ij9_de-.js:109:2)"],"meta":{}}],"startTime":1775902593735,"endTime":1775902598749.6968,"status":"failed","message":"","name":"X:/1C/NDC_1C/llm_normalizer/backend/tests/assistantStage3LifecycleAcceptanceProbe.test.ts"},{"assertionResults":[{"ancestorTitles":["assistant stage3 lifecycle prompt suite separation"],"fullName":"assistant stage3 lifecycle prompt suite separation keeps stage2 canonical prompts as regression and stage3 prompts as separate lifecycle probe","status":"passed","title":"keeps stage2 canonical prompts as regression and stage3 prompts as separate lifecycle probe","duration":1.633800000000008,"failureMessages":[],"meta":{}}],"startTime":1775902596266,"endTime":1775902596267.6338,"status":"passed","message":"","name":"X:/1C/NDC_1C/llm_normalizer/backend/tests/assistantStage3LifecyclePromptSuite.test.ts"},{"assertionResults":[{"ancestorTitles":["assistant stage4 lifecycle 97 user-facing"],"fullName":"assistant stage4 lifecycle 97 user-facing keeps lifecycle answer human and scoped without technical leakage","status":"passed","title":"keeps lifecycle answer human and scoped without technical leakage","duration":20.489599999999996,"failureMessages":[],"meta":{}}],"startTime":1775902594944,"endTime":1775902594964.4895,"status":"passed","message":"","name":"X:/1C/NDC_1C/llm_normalizer/backend/tests/assistantStage4Lifecycle97UserFacing.test.ts"},{"assertionResults":[{"ancestorTitles":["stage4 wave4 user-facing answer patch"],"fullName":"stage4 wave4 user-facing answer patch renders problem-first causal answer and hides internal debug fragments","status":"passed","title":"renders problem-first causal answer and hides internal debug fragments","duration":10.383600000000001,"failureMessages":[],"meta":{}},{"ancestorTitles":["stage4 wave4 user-facing answer patch"],"fullName":"stage4 wave4 user-facing answer patch marks weak single-signal contour as potentially noisy","status":"passed","title":"marks weak single-signal contour as potentially noisy","duration":1.1329999999999814,"failureMessages":[],"meta":{}},{"ancestorTitles":["stage4 wave4 user-facing answer patch"],"fullName":"stage4 wave4 user-facing answer patch changes top-level answer when graph causal signals are present","status":"passed","title":"changes top-level answer when graph causal signals are present","duration":2.211500000000001,"failureMessages":[],"meta":{}}],"startTime":1775902595058,"endTime":1775902595072.2114,"status":"passed","message":"","name":"X:/1C/NDC_1C/llm_normalizer/backend/tests/assistantStage4Wave4UserFacing.test.ts"},{"assertionResults":[{"ancestorTitles":["assistant turn attempt input builder"],"fullName":"assistant turn attempt input builder builds address runtime input from user turn and organization scope","status":"passed","title":"builds address runtime input from user turn and organization scope","duration":1.1414999999999793,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant turn attempt input builder"],"fullName":"assistant turn attempt input builder builds deep runtime input with investigation state and address meta","status":"passed","title":"builds deep runtime input with investigation state and address meta","duration":0.25449999999997885,"failureMessages":[],"meta":{}}],"startTime":1775902596380,"endTime":1775902596381.2544,"status":"passed","message":"","name":"X:/1C/NDC_1C/llm_normalizer/backend/tests/assistantTurnAttemptInputBuilder.test.ts"},{"assertionResults":[{"ancestorTitles":["assistant turn attempt runtime adapter"],"fullName":"assistant turn attempt runtime adapter returns address response and skips deep runtime when address lane handled the turn","status":"passed","title":"returns address response and skips deep runtime when address lane handled the turn","duration":3.6477999999999895,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant turn attempt runtime adapter"],"fullName":"assistant turn attempt runtime adapter falls through to deep runtime when address lane does not return final response","status":"passed","title":"falls through to deep runtime when address lane does not return final response","duration":0.8452000000000055,"failureMessages":[],"meta":{}}],"startTime":1775902595282,"endTime":1775902595286.8452,"status":"passed","message":"","name":"X:/1C/NDC_1C/llm_normalizer/backend/tests/assistantTurnAttemptRuntimeAdapter.test.ts"},{"assertionResults":[{"ancestorTitles":["assistant turn commit runtime adapter"],"fullName":"assistant turn commit runtime adapter appends item, persists existing session, clones conversation and logs event","status":"passed","title":"appends item, persists existing session, clones conversation and logs event","duration":2.004000000000019,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant turn commit runtime adapter"],"fullName":"assistant turn commit runtime adapter skips persist when session is missing and still logs with empty conversation","status":"passed","title":"skips persist when session is missing and still logs with empty conversation","duration":0.6580999999999904,"failureMessages":[],"meta":{}}],"startTime":1775902596069,"endTime":1775902596071.6582,"status":"passed","message":"","name":"X:/1C/NDC_1C/llm_normalizer/backend/tests/assistantTurnCommitRuntimeAdapter.test.ts"},{"assertionResults":[{"ancestorTitles":["assistant turn runtime deps adapter"],"fullName":"assistant turn runtime deps adapter builds runtime deps with service wrappers and static flags/defaults","status":"passed","title":"builds runtime deps with service wrappers and static flags/defaults","duration":3.659400000000005,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant turn runtime deps adapter"],"fullName":"assistant turn runtime deps adapter preserves helper functions in merged deps payload","status":"passed","title":"preserves helper functions in merged deps payload","duration":0.43729999999999336,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant turn runtime deps adapter"],"fullName":"assistant turn runtime deps adapter preserves method context for stateful service instances","status":"passed","title":"preserves method context for stateful service instances","duration":0.30469999999999686,"failureMessages":[],"meta":{}}],"startTime":1775902595476,"endTime":1775902595480.4373,"status":"passed","message":"","name":"X:/1C/NDC_1C/llm_normalizer/backend/tests/assistantTurnRuntimeDepsAdapter.test.ts"},{"assertionResults":[{"ancestorTitles":["assistant turn runtime input builder"],"fullName":"assistant turn runtime input builder builds bootstrap runtime input from shared deps","status":"passed","title":"builds bootstrap runtime input from shared deps","duration":2.4416999999999973,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant turn runtime input builder"],"fullName":"assistant turn runtime input builder builds address attempt input and preserves address context mapping","status":"passed","title":"builds address attempt input and preserves address context mapping","duration":1.8532000000000153,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant turn runtime input builder"],"fullName":"assistant turn runtime input builder builds deep attempt input with shared guards and state hooks","status":"passed","title":"builds deep attempt input with shared guards and state hooks","duration":0.630500000000012,"failureMessages":[],"meta":{}}],"startTime":1775902595228,"endTime":1775902595232.6306,"status":"passed","message":"","name":"X:/1C/NDC_1C/llm_normalizer/backend/tests/assistantTurnRuntimeInputBuilder.test.ts"},{"assertionResults":[{"ancestorTitles":["assistant user turn bootstrap runtime adapter"],"fullName":"assistant user turn bootstrap runtime adapter normalizes user message, appends user turn and persists session","status":"passed","title":"normalizes user message, appends user turn and persists session","duration":4.060200000000009,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant user turn bootstrap runtime adapter"],"fullName":"assistant user turn bootstrap runtime adapter falls back to raw message when repaired text is empty","status":"passed","title":"falls back to raw message when repaired text is empty","duration":1.1040000000000134,"failureMessages":[],"meta":{}}],"startTime":1775902595281,"endTime":1775902595286.104,"status":"passed","message":"","name":"X:/1C/NDC_1C/llm_normalizer/backend/tests/assistantUserTurnBootstrapRuntimeAdapter.test.ts"},{"assertionResults":[{"ancestorTitles":["wave10 settlement corrective regression"],"fullName":"wave10 settlement corrective regression multi_fragment_settlement_60_62_should_not_fall_into_deferred_expense","status":"passed","title":"multi_fragment_settlement_60_62_should_not_fall_into_deferred_expense","duration":18.267399999999952,"failureMessages":[],"meta":{}},{"ancestorTitles":["wave10 settlement corrective regression"],"fullName":"wave10 settlement corrective regression settlement_question_must_not_promote_vat_or_period_close_as_primary_domain_without_handoff","status":"passed","title":"settlement_question_must_not_promote_vat_or_period_close_as_primary_domain_without_handoff","duration":3.4588000000001102,"failureMessages":[],"meta":{}},{"ancestorTitles":["wave10 settlement corrective regression"],"fullName":"wave10 settlement corrective regression retrieval_empty_requirement_must_not_be_marked_covered","status":"passed","title":"retrieval_empty_requirement_must_not_be_marked_covered","duration":0.9565000000000055,"failureMessages":[],"meta":{}},{"ancestorTitles":["wave10 settlement corrective regression"],"fullName":"wave10 settlement corrective regression retrieval_ok_without_evidence_or_problem_units_must_not_be_marked_covered","status":"passed","title":"retrieval_ok_without_evidence_or_problem_units_must_not_be_marked_covered","duration":0.24510000000009313,"failureMessages":[],"meta":{}},{"ancestorTitles":["wave10 settlement corrective regression"],"fullName":"wave10 settlement corrective regression partial_coverage_answer_must_separate_confirmed_and_unconfirmed_requirements","status":"passed","title":"partial_coverage_answer_must_separate_confirmed_and_unconfirmed_requirements","duration":2.582300000000032,"failureMessages":[],"meta":{}},{"ancestorTitles":["wave10 settlement corrective regression"],"fullName":"wave10 settlement corrective regression settlement_domain_answer_must_suggest_settlement_checks_not_period_only","status":"passed","title":"settlement_domain_answer_must_suggest_settlement_checks_not_period_only","duration":2.423599999999851,"failureMessages":[],"meta":{}},{"ancestorTitles":["wave10 settlement corrective regression"],"fullName":"wave10 settlement corrective regression user_facing_answer_must_not_leak_internal_debug_for_partial_coverage_case","status":"passed","title":"user_facing_answer_must_not_leak_internal_debug_for_partial_coverage_case","duration":2.671600000000126,"failureMessages":[],"meta":{}},{"ancestorTitles":["wave10 settlement corrective regression"],"fullName":"wave10 settlement corrective regression settlement_broad_query_with_explicit_month_must_not_claim_period_missing","status":"passed","title":"settlement_broad_query_with_explicit_month_must_not_claim_period_missing","duration":2.4003000000000156,"failureMessages":[],"meta":{}},{"ancestorTitles":["wave10 settlement corrective regression"],"fullName":"wave10 settlement corrective regression settlement_answer_must_not_be_grounded_by_vat_or_deferred_expense_primary_evidence","status":"passed","title":"settlement_answer_must_not_be_grounded_by_vat_or_deferred_expense_primary_evidence","duration":3.054399999999987,"failureMessages":[],"meta":{}},{"ancestorTitles":["wave10 settlement corrective regression"],"fullName":"wave10 settlement corrective regression user_facing_answer_must_not_include_debug_payload_json_marker","status":"passed","title":"user_facing_answer_must_not_include_debug_payload_json_marker","duration":2.8834999999999127,"failureMessages":[],"meta":{}},{"ancestorTitles":["wave10 settlement corrective regression"],"fullName":"wave10 settlement corrective regression followup_on_same_settlement_case_must_bind_to_active_focus","status":"passed","title":"followup_on_same_settlement_case_must_bind_to_active_focus","duration":549.5663999999999,"failureMessages":[],"meta":{}}],"startTime":1775902594522,"endTime":1775902595111.5664,"status":"passed","message":"","name":"X:/1C/NDC_1C/llm_normalizer/backend/tests/assistantWave10SettlementCorrectiveRegression.test.ts"},{"assertionResults":[{"ancestorTitles":["wave11 data-layer recovery"],"fullName":"wave11 data-layer recovery settlement_object_trace_with_number_date_amount_must_not_require_guid_by_default","status":"passed","title":"settlement_object_trace_with_number_date_amount_must_not_require_guid_by_default","duration":94.4862,"failureMessages":[],"meta":{}},{"ancestorTitles":["wave11 data-layer recovery"],"fullName":"wave11 data-layer recovery broad_settlement_query_must_not_drop_all_retrieval_due_to_strict_purity_if_in_scope","status":"passed","title":"broad_settlement_query_must_not_drop_all_retrieval_due_to_strict_purity_if_in_scope","duration":27.081899999999962,"failureMessages":[],"meta":{}}],"startTime":1775902593821,"endTime":1775902593943.0818,"status":"passed","message":"","name":"X:/1C/NDC_1C/llm_normalizer/backend/tests/assistantWave11DataLayerRecovery.test.ts"},{"assertionResults":[{"ancestorTitles":["wave11 subject token pollution cleanup"],"fullName":"wave11 subject token pollution cleanup settlement_query_subject_tokens_must_not_include_spurious_accounts_from_dates","status":"passed","title":"settlement_query_subject_tokens_must_not_include_spurious_accounts_from_dates","duration":1.928200000000004,"failureMessages":[],"meta":{}}],"startTime":1775902596398,"endTime":1775902596399.9282,"status":"passed","message":"","name":"X:/1C/NDC_1C/llm_normalizer/backend/tests/assistantWave11SubjectTokenPollution.test.ts"},{"assertionResults":[{"ancestorTitles":["wave12 vat/month-close consistency + confidence reconciliation"],"fullName":"wave12 vat/month-close consistency + confidence reconciliation vat_query_with_strong_signal_must_override_stale_settlement_focus_hint","status":"passed","title":"vat_query_with_strong_signal_must_override_stale_settlement_focus_hint","duration":25.860799999999983,"failureMessages":[],"meta":{}},{"ancestorTitles":["wave12 vat/month-close consistency + confidence reconciliation"],"fullName":"wave12 vat/month-close consistency + confidence reconciliation month_close_query_with_strong_signal_must_override_stale_vat_focus_hint","status":"passed","title":"month_close_query_with_strong_signal_must_override_stale_vat_focus_hint","duration":4.596499999999992,"failureMessages":[],"meta":{}},{"ancestorTitles":["wave12 vat/month-close consistency + confidence reconciliation"],"fullName":"wave12 vat/month-close consistency + confidence reconciliation vat_domain_with_foreign_primary_evidence_must_degrade_to_clarification","status":"passed","title":"vat_domain_with_foreign_primary_evidence_must_degrade_to_clarification","duration":6.918300000000016,"failureMessages":[],"meta":{}},{"ancestorTitles":["wave12 vat/month-close consistency + confidence reconciliation"],"fullName":"wave12 vat/month-close consistency + confidence reconciliation month_close_domain_with_vat_primary_evidence_must_degrade_to_clarification","status":"passed","title":"month_close_domain_with_vat_primary_evidence_must_degrade_to_clarification","duration":3.787399999999991,"failureMessages":[],"meta":{}},{"ancestorTitles":["wave12 vat/month-close consistency + confidence reconciliation"],"fullName":"wave12 vat/month-close consistency + confidence reconciliation confidence_limitation_must_not_contradict_each_other","status":"passed","title":"confidence_limitation_must_not_contradict_each_other","duration":3.9890000000000043,"failureMessages":[],"meta":{}},{"ancestorTitles":["wave12 vat/month-close consistency + confidence reconciliation"],"fullName":"wave12 vat/month-close consistency + confidence reconciliation settlement_regression_must_remain_pass","status":"passed","title":"settlement_regression_must_remain_pass","duration":2.655000000000001,"failureMessages":[],"meta":{}}],"startTime":1775902594235,"endTime":1775902594283.655,"status":"passed","message":"","name":"X:/1C/NDC_1C/llm_normalizer/backend/tests/assistantWave12VatMonthCloseConsistencyRegression.test.ts"},{"assertionResults":[{"ancestorTitles":["wave13 domain fit + question-type fit + company-anchor grounding"],"fullName":"wave13 domain fit + question-type fit + company-anchor grounding settlement_query_must_keep_settlement_domain_even_if_retrieval_contains_vat_noise","status":"passed","title":"settlement_query_must_keep_settlement_domain_even_if_retrieval_contains_vat_noise","duration":23.08499999999998,"failureMessages":[],"meta":{}},{"ancestorTitles":["wave13 domain fit + question-type fit + company-anchor grounding"],"fullName":"wave13 domain fit + question-type fit + company-anchor grounding question_type_where_break_is_must_produce_localization_style_line","status":"passed","title":"question_type_where_break_is_must_produce_localization_style_line","duration":9.236100000000022,"failureMessages":[],"meta":{}},{"ancestorTitles":["wave13 domain fit + question-type fit + company-anchor grounding"],"fullName":"wave13 domain fit + question-type fit + company-anchor grounding question_type_prove_or_guess_must_explicitly_separate_proven_vs_hypothesis","status":"passed","title":"question_type_prove_or_guess_must_explicitly_separate_proven_vs_hypothesis","duration":4.227299999999985,"failureMessages":[],"meta":{}},{"ancestorTitles":["wave13 domain fit + question-type fit + company-anchor grounding"],"fullName":"wave13 domain fit + question-type fit + company-anchor grounding anchor_usage_lines_must_be_present_when_company_anchors_are_used","status":"passed","title":"anchor_usage_lines_must_be_present_when_company_anchors_are_used","duration":3.1389999999999816,"failureMessages":[],"meta":{}},{"ancestorTitles":["wave13 domain fit + question-type fit + company-anchor grounding"],"fullName":"wave13 domain fit + question-type fit + company-anchor grounding anchor_usage_must_be_honest_when_part_of_anchors_not_confirmed","status":"passed","title":"anchor_usage_must_be_honest_when_part_of_anchors_not_confirmed","duration":4.035799999999995,"failureMessages":[],"meta":{}},{"ancestorTitles":["wave13 domain fit + question-type fit + company-anchor grounding"],"fullName":"wave13 domain fit + question-type fit + company-anchor grounding answers_for_different_question_types_must_not_collapse_to_same_generic_pattern","status":"passed","title":"answers_for_different_question_types_must_not_collapse_to_same_generic_pattern","duration":5.608299999999986,"failureMessages":[],"meta":{}}],"startTime":1775902594494,"endTime":1775902594543.6084,"status":"passed","message":"","name":"X:/1C/NDC_1C/llm_normalizer/backend/tests/assistantWave13DomainFitQuestionTypeAnchorRegression.test.ts"},{"assertionResults":[{"ancestorTitles":["wave15 question-type contract + first-check relevance"],"fullName":"wave15 question-type contract + first-check relevance prove_or_guess answer keeps proof-vs-hypothesis framing","status":"passed","title":"prove_or_guess answer keeps proof-vs-hypothesis framing","duration":28.013800000000003,"failureMessages":[],"meta":{}},{"ancestorTitles":["wave15 question-type contract + first-check relevance"],"fullName":"wave15 question-type contract + first-check relevance grounded_on answer is basis-oriented, not generic mechanism dump","status":"passed","title":"grounded_on answer is basis-oriented, not generic mechanism dump","duration":8.127499999999998,"failureMessages":[],"meta":{}},{"ancestorTitles":["wave15 question-type contract + first-check relevance"],"fullName":"wave15 question-type contract + first-check relevance chains question provides complete-vs-incomplete framing","status":"passed","title":"chains question provides complete-vs-incomplete framing","duration":2.8494999999999777,"failureMessages":[],"meta":{}},{"ancestorTitles":["wave15 question-type contract + first-check relevance"],"fullName":"wave15 question-type contract + first-check relevance where_break_is answer localizes break node","status":"passed","title":"where_break_is answer localizes break node","duration":3.1754000000000246,"failureMessages":[],"meta":{}},{"ancestorTitles":["wave15 question-type contract + first-check relevance"],"fullName":"wave15 question-type contract + first-check relevance what_to_check_first answer gives short operational route","status":"passed","title":"what_to_check_first answer gives short operational route","duration":2.6374000000000137,"failureMessages":[],"meta":{}}],"startTime":1775902594839,"endTime":1775902594883.6375,"status":"passed","message":"","name":"X:/1C/NDC_1C/llm_normalizer/backend/tests/assistantWave15QuestionTypeContractFirstCheckRegression.test.ts"},{"assertionResults":[{"ancestorTitles":["wave16 live corrective pass regressions"],"fullName":"wave16 live corrective pass regressions removes leaked debug payload scaffolding from user-facing reply","status":"passed","title":"removes leaked debug payload scaffolding from user-facing reply","duration":23.590599999999995,"failureMessages":[],"meta":{}},{"ancestorTitles":["wave16 live corrective pass regressions"],"fullName":"wave16 live corrective pass regressions does not claim missing period when normalization already extracted explicit period","status":"passed","title":"does not claim missing period when normalization already extracted explicit period","duration":5.08420000000001,"failureMessages":[],"meta":{}},{"ancestorTitles":["wave16 live corrective pass regressions"],"fullName":"wave16 live corrective pass regressions blocks VAT primary synthesis when top evidence is cross-domain polluted","status":"passed","title":"blocks VAT primary synthesis when top evidence is cross-domain polluted","duration":3.7727000000000146,"failureMessages":[],"meta":{}},{"ancestorTitles":["wave16 live corrective pass regressions"],"fullName":"wave16 live corrective pass regressions uses VAT-specific partial-coverage wording instead of generic chain template","status":"passed","title":"uses VAT-specific partial-coverage wording instead of generic chain template","duration":2.388300000000015,"failureMessages":[],"meta":{}},{"ancestorTitles":["wave16 live corrective pass regressions"],"fullName":"wave16 live corrective pass regressions renders RBP answer in RBP language with RBP-first checks","status":"passed","title":"renders RBP answer in RBP language with RBP-first checks","duration":4.5093000000000245,"failureMessages":[],"meta":{}},{"ancestorTitles":["wave16 live corrective pass regressions"],"fullName":"wave16 live corrective pass regressions does not collapse fixed-asset amortization question into month-close primary narrative","status":"passed","title":"does not collapse fixed-asset amortization question into month-close primary narrative","duration":4.625399999999985,"failureMessages":[],"meta":{}}],"startTime":1775902594271,"endTime":1775902594314.6255,"status":"passed","message":"","name":"X:/1C/NDC_1C/llm_normalizer/backend/tests/assistantWave16LiveCorrectivePassRegression.test.ts"},{"assertionResults":[{"ancestorTitles":["wave16 residual fail cleanup"],"fullName":"wave16 residual fail cleanup q10-style VAT query must not derive account scope from percent/amount fragments","status":"passed","title":"q10-style VAT query must not derive account scope from percent/amount fragments","duration":19.95150000000001,"failureMessages":[],"meta":{}},{"ancestorTitles":["wave16 residual fail cleanup"],"fullName":"wave16 residual fail cleanup q13-style broad VAT query on batch route must stay VAT-domain","status":"passed","title":"q13-style broad VAT query on batch route must stay VAT-domain","duration":17.126800000000003,"failureMessages":[],"meta":{}},{"ancestorTitles":["wave16 residual fail cleanup"],"fullName":"wave16 residual fail cleanup q06 first-check should be settlement-specific for prove_or_guess without explicit account tokens","status":"passed","title":"q06 first-check should be settlement-specific for prove_or_guess without explicit account tokens","duration":22.69040000000001,"failureMessages":[],"meta":{}},{"ancestorTitles":["wave16 residual fail cleanup"],"fullName":"wave16 residual fail cleanup q12-like question should resolve prove_or_guess instead of chain classification","status":"passed","title":"q12-like question should resolve prove_or_guess instead of chain classification","duration":0.7549000000000206,"failureMessages":[],"meta":{}},{"ancestorTitles":["wave16 residual fail cleanup"],"fullName":"wave16 residual fail cleanup why_breaks short line should avoid generic collapse and keep domain-specific mechanism","status":"passed","title":"why_breaks short line should avoid generic collapse and keep domain-specific mechanism","duration":4.559100000000001,"failureMessages":[],"meta":{}},{"ancestorTitles":["wave16 residual fail cleanup"],"fullName":"wave16 residual fail cleanup VAT why_breaks first-check must include VAT-specific checks","status":"passed","title":"VAT why_breaks first-check must include VAT-specific checks","duration":3.344799999999964,"failureMessages":[],"meta":{}}],"startTime":1775902594332,"endTime":1775902594400.3447,"status":"passed","message":"","name":"X:/1C/NDC_1C/llm_normalizer/backend/tests/assistantWave16ResidualCleanupRegression.test.ts"},{"assertionResults":[{"ancestorTitles":["stage4 wave5 P0 domain purity + route discipline regression"],"fullName":"stage4 wave5 P0 domain purity + route discipline regression keeps top-3 domain-pure and reroutes symptom/lifecycle intents away from canonical path","status":"passed","title":"keeps top-3 domain-pure and reroutes symptom/lifecycle intents away from canonical path","duration":63.16099999999997,"failureMessages":[],"meta":{}}],"startTime":1775902594636,"endTime":1775902594699.161,"status":"passed","message":"","name":"X:/1C/NDC_1C/llm_normalizer/backend/tests/assistantWave5P0DomainPurityRegression.test.ts"},{"assertionResults":[{"ancestorTitles":["assistant wave6 problem-first answer contract"],"fullName":"assistant wave6 problem-first answer contract enforces leakage guard in direct user-facing answer","status":"passed","title":"enforces leakage guard in direct user-facing answer","duration":22.721499999999992,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant wave6 problem-first answer contract"],"fullName":"assistant wave6 problem-first answer contract keeps narrative mechanism-first and avoids entity-list direct answer","status":"passed","title":"keeps narrative mechanism-first and avoids entity-list direct answer","duration":6.073099999999982,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant wave6 problem-first answer contract"],"fullName":"assistant wave6 problem-first answer contract does not expose route/profile explanation in user-facing text","status":"passed","title":"does not expose route/profile explanation in user-facing text","duration":4.566600000000022,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant wave6 problem-first answer contract"],"fullName":"assistant wave6 problem-first answer contract collapses duplicate problem lines for the same mechanism","status":"passed","title":"collapses duplicate problem lines for the same mechanism","duration":3.6753999999999962,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant wave6 problem-first answer contract"],"fullName":"assistant wave6 problem-first answer contract shows explicit limitation when period is missing","status":"passed","title":"shows explicit limitation when period is missing","duration":4.747100000000017,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant wave6 problem-first answer contract"],"fullName":"assistant wave6 problem-first answer contract returns short accountant-readable answers for P0 domains without technical dump","status":"passed","title":"returns short accountant-readable answers for P0 domains without technical dump","duration":10.507600000000025,"failureMessages":[],"meta":{}}],"startTime":1775902594494,"endTime":1775902594546.5076,"status":"passed","message":"","name":"X:/1C/NDC_1C/llm_normalizer/backend/tests/assistantWave6ProblemFirstAnswerContract.test.ts"},{"assertionResults":[{"ancestorTitles":["conversation export regression"],"fullName":"conversation export regression default export excludes debug payload sections and keeps user-facing text","status":"passed","title":"default export excludes debug payload sections and keeps user-facing text","duration":2.386599999999987,"failureMessages":[],"meta":{}},{"ancestorTitles":["conversation export regression"],"fullName":"conversation export regression technical export includes debug payload in dedicated section only","status":"passed","title":"technical export includes debug payload in dedicated section only","duration":0.28249999999999886,"failureMessages":[],"meta":{}},{"ancestorTitles":["conversation export regression"],"fullName":"conversation export regression sanitizeConversationExportText removes technical tails","status":"passed","title":"sanitizeConversationExportText removes technical tails","duration":0.15709999999998558,"failureMessages":[],"meta":{}}],"startTime":1775902595481,"endTime":1775902595484.2825,"status":"passed","message":"","name":"X:/1C/NDC_1C/llm_normalizer/backend/tests/conversationExportRegression.test.ts"},{"assertionResults":[{"ancestorTitles":["POST /api/eval/run"],"fullName":"POST /api/eval/run runs v2 eval using inline rawQuestions batch","status":"passed","title":"runs v2 eval using inline rawQuestions batch","duration":74.9914,"failureMessages":[],"meta":{}}],"startTime":1775902594671,"endTime":1775902594745.9915,"status":"passed","message":"","name":"X:/1C/NDC_1C/llm_normalizer/backend/tests/evalEndpoint.test.ts"},{"assertionResults":[{"ancestorTitles":["investigation_state flow scaffolding"],"fullName":"investigation_state flow scaffolding keeps bounded investigation_state across follow-up turns","status":"passed","title":"keeps bounded investigation_state across follow-up turns","duration":424.32569999999987,"failureMessages":[],"meta":{}}],"startTime":1775902594670,"endTime":1775902595094.3257,"status":"passed","message":"","name":"X:/1C/NDC_1C/llm_normalizer/backend/tests/investigationStateFlow.test.ts"},{"assertionResults":[{"ancestorTitles":["stage3 lifecycle registry and resolver wave2"],"fullName":"stage3 lifecycle registry and resolver wave2 exposes all lifecycle domains in the registry","status":"passed","title":"exposes all lifecycle domains in the registry","duration":1.2708000000000084,"failureMessages":[],"meta":{}},{"ancestorTitles":["stage3 lifecycle registry and resolver wave2"],"fullName":"stage3 lifecycle registry and resolver wave2 infers lifecycle domain for all covered stage3 domains","status":"passed","title":"infers lifecycle domain for all covered stage3 domains","duration":2.1847999999999956,"failureMessages":[],"meta":{}},{"ancestorTitles":["stage3 lifecycle registry and resolver wave2"],"fullName":"stage3 lifecycle registry and resolver wave2 normalizes unknown explicit states against registry and records limitations","status":"passed","title":"normalizes unknown explicit states against registry and records limitations","duration":0.7660000000000196,"failureMessages":[],"meta":{}},{"ancestorTitles":["stage3 lifecycle registry and resolver wave2"],"fullName":"stage3 lifecycle registry and resolver wave2 infers missing transition from registry transition path","status":"passed","title":"infers missing transition from registry transition path","duration":0.36360000000001946,"failureMessages":[],"meta":{}},{"ancestorTitles":["stage3 lifecycle registry and resolver wave2"],"fullName":"stage3 lifecycle registry and resolver wave2 builds previous state chain from registry model","status":"passed","title":"builds previous state chain from registry model","duration":0.29760000000001696,"failureMessages":[],"meta":{}}],"startTime":1775902595285,"endTime":1775902595290.2976,"status":"passed","message":"","name":"X:/1C/NDC_1C/llm_normalizer/backend/tests/lifecycleRegistryResolverWave2.test.ts"},{"assertionResults":[{"ancestorTitles":["lifecycle runtime stage3"],"fullName":"lifecycle runtime stage3 resolves stale missing transition for bank settlement chains","status":"passed","title":"resolves stale missing transition for bank settlement chains","duration":2.4946999999999946,"failureMessages":[],"meta":{}},{"ancestorTitles":["lifecycle runtime stage3"],"fullName":"lifecycle runtime stage3 classifies cross-branch conflicts for VAT flow","status":"passed","title":"classifies cross-branch conflicts for VAT flow","duration":0.8718999999999824,"failureMessages":[],"meta":{}},{"ancestorTitles":["lifecycle runtime stage3"],"fullName":"lifecycle runtime stage3 sorts lifecycle-ranked units by lifecycle severity and ranking score","status":"passed","title":"sorts lifecycle-ranked units by lifecycle severity and ranking score","duration":0.7267999999999972,"failureMessages":[],"meta":{}}],"startTime":1775902595830,"endTime":1775902595834.7268,"status":"passed","message":"","name":"X:/1C/NDC_1C/llm_normalizer/backend/tests/lifecycleRuntime.test.ts"},{"assertionResults":[{"ancestorTitles":["stage3 lifecycle probe semantics"],"fullName":"stage3 lifecycle probe semantics validates lifecycle acceptance targets on synthetic runtime inputs","status":"passed","title":"validates lifecycle acceptance targets on synthetic runtime inputs","duration":4.001299999999986,"failureMessages":[],"meta":{}}],"startTime":1775902595469,"endTime":1775902595473.0012,"status":"passed","message":"","name":"X:/1C/NDC_1C/llm_normalizer/backend/tests/lifecycleStage3AcceptanceProbeSemantics.test.ts"},{"assertionResults":[{"ancestorTitles":["POST /api/normalize"],"fullName":"POST /api/normalize returns normalized v1 payload in mock mode","status":"passed","title":"returns normalized v1 payload in mock mode","duration":62.41039999999998,"failureMessages":[],"meta":{}},{"ancestorTitles":["POST /api/normalize"],"fullName":"POST /api/normalize returns normalized v2 payload in mock mode","status":"passed","title":"returns normalized v2 payload in mock mode","duration":53.774900000000116,"failureMessages":[],"meta":{}},{"ancestorTitles":["POST /api/normalize"],"fullName":"POST /api/normalize returns normalized v2.0.1 payload in mock mode with execution_readiness","status":"passed","title":"returns normalized v2.0.1 payload in mock mode with execution_readiness","duration":29.83979999999997,"failureMessages":[],"meta":{}},{"ancestorTitles":["POST /api/normalize"],"fullName":"POST /api/normalize returns normalized v2.0.2 payload in mock mode with route_status and no_route_reason","status":"passed","title":"returns normalized v2.0.2 payload in mock mode with route_status and no_route_reason","duration":26.532600000000002,"failureMessages":[],"meta":{}}],"startTime":1775902594670,"endTime":1775902594842.5327,"status":"passed","message":"","name":"X:/1C/NDC_1C/llm_normalizer/backend/tests/normalizeEndpoint.test.ts"},{"assertionResults":[{"ancestorTitles":["NormalizerService coercion layer"],"fullName":"NormalizerService coercion layer coerces malformed v2.0.2 local payload into a usable routed fragment","status":"passed","title":"coerces malformed v2.0.2 local payload into a usable routed fragment","duration":42.379999999999995,"failureMessages":[],"meta":{}},{"ancestorTitles":["NormalizerService coercion layer"],"fullName":"NormalizerService coercion layer coerces period_type month payload into explicit YYYY-MM time scope","status":"passed","title":"coerces period_type month payload into explicit YYYY-MM time scope","duration":21.463499999999982,"failureMessages":[],"meta":{}}],"startTime":1775902594527,"endTime":1775902594591.4634,"status":"passed","message":"","name":"X:/1C/NDC_1C/llm_normalizer/backend/tests/normalizerServiceCoercion.test.ts"},{"assertionResults":[{"ancestorTitles":["openai local responses fallback"],"fullName":"openai local responses fallback falls back to /chat/completions when /responses payload is parseable JSON but has no output_text","status":"passed","title":"falls back to /chat/completions when /responses payload is parseable JSON but has no output_text","duration":5.3259000000000185,"failureMessages":[],"meta":{}},{"ancestorTitles":["openai local responses fallback"],"fullName":"openai local responses fallback retries alternative local base when endpoint mismatch payload is returned for chat completions","status":"passed","title":"retries alternative local base when endpoint mismatch payload is returned for chat completions","duration":1.726699999999994,"failureMessages":[],"meta":{}}],"startTime":1775902595155,"endTime":1775902595161.7268,"status":"passed","message":"","name":"X:/1C/NDC_1C/llm_normalizer/backend/tests/openaiResponsesClientLocalFallback.test.ts"},{"assertionResults":[{"ancestorTitles":["problemUnitAssembler scaffold"],"fullName":"problemUnitAssembler scaffold groups candidate evidence by route/source/pattern signature","status":"passed","title":"groups candidate evidence by route/source/pattern signature","duration":1.8687999999999931,"failureMessages":[],"meta":{}},{"ancestorTitles":["problemUnitAssembler scaffold"],"fullName":"problemUnitAssembler scaffold detects baseline problem unit type from anomaly hints","status":"passed","title":"detects baseline problem unit type from anomaly hints","duration":0.31860000000000355,"failureMessages":[],"meta":{}},{"ancestorTitles":["problemUnitAssembler scaffold"],"fullName":"problemUnitAssembler scaffold collapses duplicate problem units by signature","status":"passed","title":"collapses duplicate problem units by signature","duration":0.619400000000013,"failureMessages":[],"meta":{}},{"ancestorTitles":["problemUnitAssembler scaffold"],"fullName":"problemUnitAssembler scaffold assembles problem units and summary with bounded scaffold fields","status":"passed","title":"assembles problem units and summary with bounded scaffold fields","duration":3.001800000000003,"failureMessages":[],"meta":{}}],"startTime":1775902595270,"endTime":1775902595276.0017,"status":"passed","message":"","name":"X:/1C/NDC_1C/llm_normalizer/backend/tests/problemUnitAssembler.test.ts"},{"assertionResults":[{"ancestorTitles":["promptBuilder"],"fullName":"promptBuilder loads default prompts","status":"passed","title":"loads default prompts","duration":1.452399999999983,"failureMessages":[],"meta":{}},{"ancestorTitles":["promptBuilder"],"fullName":"promptBuilder exposes v1, v1.1, v1.1.1, v1.1.2, v1.1.2.1, v2, v2.0.1 and v2.0.2 builtin presets","status":"passed","title":"exposes v1, v1.1, v1.1.1, v1.1.2, v1.1.2.1, v2, v2.0.1 and v2.0.2 builtin presets","duration":1.715599999999995,"failureMessages":[],"meta":{}},{"ancestorTitles":["promptBuilder"],"fullName":"promptBuilder merges user prompt values","status":"passed","title":"merges user prompt values","duration":0.37980000000001723,"failureMessages":[],"meta":{}}],"startTime":1775902595407,"endTime":1775902595410.7156,"status":"passed","message":"","name":"X:/1C/NDC_1C/llm_normalizer/backend/tests/promptBuilder.test.ts"},{"assertionResults":[{"ancestorTitles":["questionTypeResolver"],"fullName":"questionTypeResolver resolves what_to_check_first for operational check phrasing","status":"passed","title":"resolves what_to_check_first for operational check phrasing","duration":2.8422999999999945,"failureMessages":[],"meta":{}},{"ancestorTitles":["questionTypeResolver"],"fullName":"questionTypeResolver resolves where_break_is for localization phrasing","status":"passed","title":"resolves where_break_is for localization phrasing","duration":1.2898000000000138,"failureMessages":[],"meta":{}},{"ancestorTitles":["questionTypeResolver"],"fullName":"questionTypeResolver resolves prove_or_guess without collapsing to generic yes/no","status":"passed","title":"resolves prove_or_guess without collapsing to generic yes/no","duration":0.41909999999998604,"failureMessages":[],"meta":{}},{"ancestorTitles":["questionTypeResolver"],"fullName":"questionTypeResolver resolves grounded_on when question asks for evidence basis","status":"passed","title":"resolves grounded_on when question asks for evidence basis","duration":0.11720000000002528,"failureMessages":[],"meta":{}},{"ancestorTitles":["questionTypeResolver"],"fullName":"questionTypeResolver resolves chains completeness classification questions","status":"passed","title":"resolves chains completeness classification questions","duration":0.08789999999999054,"failureMessages":[],"meta":{}},{"ancestorTitles":["questionTypeResolver"],"fullName":"questionTypeResolver falls back to why_breaks for generic why-question","status":"passed","title":"falls back to why_breaks for generic why-question","duration":0.09860000000000468,"failureMessages":[],"meta":{}},{"ancestorTitles":["questionTypeResolver"],"fullName":"questionTypeResolver keeps generic non-why questions as unknown","status":"passed","title":"keeps generic non-why questions as unknown","duration":0.15540000000001442,"failureMessages":[],"meta":{}}],"startTime":1775902595218,"endTime":1775902595223.4192,"status":"passed","message":"","name":"X:/1C/NDC_1C/llm_normalizer/backend/tests/questionTypeResolver.test.ts"},{"assertionResults":[{"ancestorTitles":["retrieval dual payload compatibility for graph runtime"],"fullName":"retrieval dual payload compatibility for graph runtime keeps stage2 payload when graph runtime flag is OFF","status":"passed","title":"keeps stage2 payload when graph runtime flag is OFF","duration":15.295899999999989,"failureMessages":[],"meta":{}},{"ancestorTitles":["retrieval dual payload compatibility for graph runtime"],"fullName":"retrieval dual payload compatibility for graph runtime adds graph runtime payload when graph runtime flag is ON","status":"passed","title":"adds graph runtime payload when graph runtime flag is ON","duration":15.873799999999989,"failureMessages":[],"meta":{}}],"startTime":1775902594797,"endTime":1775902594827.8738,"status":"passed","message":"","name":"X:/1C/NDC_1C/llm_normalizer/backend/tests/retrievalGraphRuntimeDualPayload.test.ts"},{"assertionResults":[{"ancestorTitles":["retrieval lifecycle runtime rollout"],"fullName":"retrieval lifecycle runtime rollout keeps Stage 2 payload when lifecycle runtime flag is OFF","status":"passed","title":"keeps Stage 2 payload when lifecycle runtime flag is OFF","duration":23.907600000000002,"failureMessages":[],"meta":{}},{"ancestorTitles":["retrieval lifecycle runtime rollout"],"fullName":"retrieval lifecycle runtime rollout adds lifecycle fields to problem units when lifecycle runtime flag is ON","status":"passed","title":"adds lifecycle fields to problem units when lifecycle runtime flag is ON","duration":9.692199999999985,"failureMessages":[],"meta":{}}],"startTime":1775902594891,"endTime":1775902594924.6921,"status":"passed","message":"","name":"X:/1C/NDC_1C/llm_normalizer/backend/tests/retrievalLifecycleRuntimeRollout.test.ts"},{"assertionResults":[{"ancestorTitles":["retrieval dual payload compatibility for problem units"],"fullName":"retrieval dual payload compatibility for problem units keeps legacy payload intact when FEATURE_ASSISTANT_PROBLEM_UNITS_V1 is OFF","status":"passed","title":"keeps legacy payload intact when FEATURE_ASSISTANT_PROBLEM_UNITS_V1 is OFF","duration":13.783999999999992,"failureMessages":[],"meta":{}},{"ancestorTitles":["retrieval dual payload compatibility for problem units"],"fullName":"retrieval dual payload compatibility for problem units adds Stage 2 dual payload fields when FEATURE_ASSISTANT_PROBLEM_UNITS_V1 is ON","status":"passed","title":"adds Stage 2 dual payload fields when FEATURE_ASSISTANT_PROBLEM_UNITS_V1 is ON","duration":20.805800000000005,"failureMessages":[],"meta":{}}],"startTime":1775902594784,"endTime":1775902594818.806,"status":"passed","message":"","name":"X:/1C/NDC_1C/llm_normalizer/backend/tests/retrievalProblemUnitDualPayload.test.ts"},{"assertionResults":[{"ancestorTitles":["retrieval evidence enrichment"],"fullName":"retrieval evidence enrichment builds deterministic canonical source_ref from pointer/source","status":"passed","title":"builds deterministic canonical source_ref from pointer/source","duration":316.74760000000003,"failureMessages":[],"meta":{}},{"ancestorTitles":["retrieval evidence enrichment"],"fullName":"retrieval evidence enrichment uses honest weak-evidence fallback when mechanism is not reliable","status":"passed","title":"uses honest weak-evidence fallback when mechanism is not reliable","duration":10.80460000000005,"failureMessages":[],"meta":{}},{"ancestorTitles":["retrieval evidence enrichment"],"fullName":"retrieval evidence enrichment maps explicit limitation to reason-coded structure","status":"passed","title":"maps explicit limitation to reason-coded structure","duration":22.69010000000003,"failureMessages":[],"meta":{}},{"ancestorTitles":["retrieval evidence enrichment"],"fullName":"retrieval evidence enrichment keeps legacy inferred mechanism when enrichment flag is OFF","status":"passed","title":"keeps legacy inferred mechanism when enrichment flag is OFF","duration":7.851700000000051,"failureMessages":[],"meta":{}}],"startTime":1775902593689,"endTime":1775902594047.8518,"status":"passed","message":"","name":"X:/1C/NDC_1C/llm_normalizer/backend/tests/retrievalResultEvidenceEnrichment.test.ts"},{"assertionResults":[{"ancestorTitles":["routeHintAdapter"],"fullName":"routeHintAdapter builds v1 route hint summary","status":"passed","title":"builds v1 route hint summary","duration":1.7134000000000071,"failureMessages":[],"meta":{}},{"ancestorTitles":["routeHintAdapter"],"fullName":"routeHintAdapter builds v2 deterministic route simulation","status":"passed","title":"builds v2 deterministic route simulation","duration":1.119400000000013,"failureMessages":[],"meta":{}},{"ancestorTitles":["routeHintAdapter"],"fullName":"routeHintAdapter builds router input contract for v1","status":"passed","title":"builds router input contract for v1","duration":0.2342999999999904,"failureMessages":[],"meta":{}},{"ancestorTitles":["routeHintAdapter"],"fullName":"routeHintAdapter keeps v2.0.1 soft assumptions executable in deterministic routing","status":"passed","title":"keeps v2.0.1 soft assumptions executable in deterministic routing","duration":0.5700999999999965,"failureMessages":[],"meta":{}},{"ancestorTitles":["routeHintAdapter"],"fullName":"routeHintAdapter uses explicit v2.0.2 route_status/no_route_reason contract","status":"passed","title":"uses explicit v2.0.2 route_status/no_route_reason contract","duration":0.3674000000000035,"failureMessages":[],"meta":{}},{"ancestorTitles":["routeHintAdapter"],"fullName":"routeHintAdapter promotes lifecycle chain intent to hybrid route even without multi-entity flag","status":"passed","title":"promotes lifecycle chain intent to hybrid route even without multi-entity flag","duration":0.13059999999998695,"failureMessages":[],"meta":{}},{"ancestorTitles":["routeHintAdapter"],"fullName":"routeHintAdapter promotes mixed-ambiguity symptom fragment to hybrid when domain anchors are present","status":"passed","title":"promotes mixed-ambiguity symptom fragment to hybrid when domain anchors are present","duration":0.4224999999999852,"failureMessages":[],"meta":{}},{"ancestorTitles":["routeHintAdapter"],"fullName":"routeHintAdapter keeps canonical path only for factual fragments without symptom/lifecycle markers","status":"passed","title":"keeps canonical path only for factual fragments without symptom/lifecycle markers","duration":0.23329999999998563,"failureMessages":[],"meta":{}}],"startTime":1775902595350,"endTime":1775902595355.4226,"status":"passed","message":"","name":"X:/1C/NDC_1C/llm_normalizer/backend/tests/routeHintAdapter.test.ts"},{"assertionResults":[{"ancestorTitles":["schemaValidator"],"fullName":"schemaValidator passes valid normalized payload","status":"passed","title":"passes valid normalized payload","duration":38.740399999999994,"failureMessages":[],"meta":{}},{"ancestorTitles":["schemaValidator"],"fullName":"schemaValidator fails invalid payload","status":"passed","title":"fails invalid payload","duration":0.3731999999999971,"failureMessages":[],"meta":{}},{"ancestorTitles":["schemaValidator"],"fullName":"schemaValidator passes valid normalized v2 payload","status":"passed","title":"passes valid normalized v2 payload","duration":26.360199999999992,"failureMessages":[],"meta":{}},{"ancestorTitles":["schemaValidator"],"fullName":"schemaValidator fails invalid v2 payload","status":"passed","title":"fails invalid v2 payload","duration":0.4017000000000053,"failureMessages":[],"meta":{}},{"ancestorTitles":["schemaValidator"],"fullName":"schemaValidator passes valid normalized v2.0.1 payload","status":"passed","title":"passes valid normalized v2.0.1 payload","duration":14.982100000000003,"failureMessages":[],"meta":{}},{"ancestorTitles":["schemaValidator"],"fullName":"schemaValidator passes valid normalized v2.0.2 payload","status":"passed","title":"passes valid normalized v2.0.2 payload","duration":13.98599999999999,"failureMessages":[],"meta":{}}],"startTime":1775902594209,"endTime":1775902594303.986,"status":"passed","message":"","name":"X:/1C/NDC_1C/llm_normalizer/backend/tests/schemaValidator.test.ts"},{"assertionResults":[{"ancestorTitles":["assistant session backward compatibility"],"fullName":"assistant session backward compatibility lazy-upgrades legacy session objects without investigation_state","status":"passed","title":"lazy-upgrades legacy session objects without investigation_state","duration":1.3613,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant session backward compatibility"],"fullName":"assistant session backward compatibility normalizes malformed legacy sessions with missing items array","status":"passed","title":"normalizes malformed legacy sessions with missing items array","duration":0.23059999999998126,"failureMessages":[],"meta":{}},{"ancestorTitles":["assistant session backward compatibility"],"fullName":"assistant session backward compatibility preserves optional stage2 problem_unit_state in session clone flow","status":"passed","title":"preserves optional stage2 problem_unit_state in session clone flow","duration":0.5725999999999942,"failureMessages":[],"meta":{}}],"startTime":1775902596097,"endTime":1775902596099.5725,"status":"passed","message":"","name":"X:/1C/NDC_1C/llm_normalizer/backend/tests/sessionBackwardCompat.test.ts"},{"assertionResults":[{"ancestorTitles":["stage4GraphRuntime"],"fullName":"stage4GraphRuntime builds graph bindings for deferred expense lifecycle with missing transition","status":"passed","title":"builds graph bindings for deferred expense lifecycle with missing transition","duration":7.170600000000007,"failureMessages":[],"meta":{}},{"ancestorTitles":["stage4GraphRuntime"],"fullName":"stage4GraphRuntime marks cross-branch conflicts for vat graph branches","status":"passed","title":"marks cross-branch conflicts for vat graph branches","duration":0.992999999999995,"failureMessages":[],"meta":{}},{"ancestorTitles":["stage4GraphRuntime"],"fullName":"stage4GraphRuntime infers 97 domain mapping when lifecycle domain is absent","status":"passed","title":"infers 97 domain mapping when lifecycle domain is absent","duration":0.2803000000000111,"failureMessages":[],"meta":{}}],"startTime":1775902595096,"endTime":1775902595105.2803,"status":"passed","message":"","name":"X:/1C/NDC_1C/llm_normalizer/backend/tests/stage4GraphRuntime.test.ts"}]} \ No newline at end of file diff --git a/llm_normalizer/data/eval_cases/eval-5S6BYeWJWv.report.json b/llm_normalizer/data/eval_cases/eval-5S6BYeWJWv.report.json new file mode 100644 index 0000000..a63d34d --- /dev/null +++ b/llm_normalizer/data/eval_cases/eval-5S6BYeWJWv.report.json @@ -0,0 +1,112 @@ +{ + "run_id": "eval-5S6BYeWJWv", + "timestamp": "2026-04-11T10:38:19.513Z", + "mode": "single-pass-strict", + "use_mock": true, + "prompt_version": "normalizer_v2_0_2", + "schema_version": "v2_0_2", + "dataset": { + "source": "inline_raw_questions", + "file": null, + "raw_questions_count": 2 + }, + "cases_total": 2, + "metrics": { + "schema_validation_pass_rate": 100, + "scope_detection_accuracy": null, + "scope_in_scope_rate": 100, + "multi_intent_detected_rate": 0, + "clarification_required_rate": 0, + "avg_fragments_per_message": 1, + "out_of_scope_fragment_rate": 0, + "routed_fragment_rate": 100, + "no_route_fragment_rate": 0, + "route_resolution_accuracy": null, + "no_route_precision": null, + "false_no_route_rate": null, + "execution_state_consistency_rate": 100, + "executable_with_soft_assumptions_rate": 100, + "soft_assumption_used_fragment_rate": 100, + "clarification_precision": null, + "clarification_recall": null, + "false_clarification_rate": null + }, + "budget": { + "requests_total": 0, + "retries_used": 0 + }, + "clarification_eval": { + "labeled_cases": 0, + "true_positive": 0, + "false_positive": 0, + "false_negative": 0 + }, + "route_eval": { + "labeled_cases": 0, + "correct_cases": 0, + "expected_routed_cases": 0, + "no_route_true_positive": 0, + "no_route_false_positive": 0 + }, + "scope_eval": { + "labeled_cases": 0, + "correct_cases": 0 + }, + "execution_state_eval": { + "checks_total": 2, + "checks_passed": 2 + }, + "route_distribution": { + "store_feature_risk": 1, + "hybrid_store_plus_live": 1 + }, + "fallback_distribution": { + "none": 2 + }, + "results": [ + { + "case_id": "BQ-001", + "raw_question": "Проверь счет 60 за июнь 2020", + "validation_passed": true, + "message_in_scope": true, + "scope_confidence": "high", + "contains_multiple_tasks": false, + "fragments_total": 1, + "in_scope_fragments": 1, + "out_of_scope_fragments": 0, + "unclear_fragments": 0, + "fallback_type": "none", + "predicted_route_status": "routed", + "expected_route_status": null, + "predicted_no_route_reason": null, + "expected_no_route_reason": null, + "predicted_clarification_required": false, + "expected_clarification_required": null, + "executable_with_soft_assumptions_fragments": 1, + "trace_id": "bi53megxPkVDpq", + "request_count_for_case": 0 + }, + { + "case_id": "BQ-002", + "raw_question": "Покажи риски по НДС и по закрытию", + "validation_passed": true, + "message_in_scope": true, + "scope_confidence": "high", + "contains_multiple_tasks": false, + "fragments_total": 1, + "in_scope_fragments": 1, + "out_of_scope_fragments": 0, + "unclear_fragments": 0, + "fallback_type": "none", + "predicted_route_status": "routed", + "expected_route_status": null, + "predicted_no_route_reason": null, + "expected_no_route_reason": null, + "predicted_clarification_required": false, + "expected_clarification_required": null, + "executable_with_soft_assumptions_fragments": 1, + "trace_id": "ew725J5aRLs1XU", + "request_count_for_case": 0 + } + ] +} \ No newline at end of file diff --git a/llm_normalizer/data/eval_cases/eval-D1gt1OyBqh.report.json b/llm_normalizer/data/eval_cases/eval-D1gt1OyBqh.report.json new file mode 100644 index 0000000..9d4b413 --- /dev/null +++ b/llm_normalizer/data/eval_cases/eval-D1gt1OyBqh.report.json @@ -0,0 +1,112 @@ +{ + "run_id": "eval-D1gt1OyBqh", + "timestamp": "2026-04-11T10:35:37.557Z", + "mode": "single-pass-strict", + "use_mock": true, + "prompt_version": "normalizer_v2_0_2", + "schema_version": "v2_0_2", + "dataset": { + "source": "inline_raw_questions", + "file": null, + "raw_questions_count": 2 + }, + "cases_total": 2, + "metrics": { + "schema_validation_pass_rate": 100, + "scope_detection_accuracy": null, + "scope_in_scope_rate": 100, + "multi_intent_detected_rate": 0, + "clarification_required_rate": 0, + "avg_fragments_per_message": 1, + "out_of_scope_fragment_rate": 0, + "routed_fragment_rate": 100, + "no_route_fragment_rate": 0, + "route_resolution_accuracy": null, + "no_route_precision": null, + "false_no_route_rate": null, + "execution_state_consistency_rate": 100, + "executable_with_soft_assumptions_rate": 100, + "soft_assumption_used_fragment_rate": 100, + "clarification_precision": null, + "clarification_recall": null, + "false_clarification_rate": null + }, + "budget": { + "requests_total": 0, + "retries_used": 0 + }, + "clarification_eval": { + "labeled_cases": 0, + "true_positive": 0, + "false_positive": 0, + "false_negative": 0 + }, + "route_eval": { + "labeled_cases": 0, + "correct_cases": 0, + "expected_routed_cases": 0, + "no_route_true_positive": 0, + "no_route_false_positive": 0 + }, + "scope_eval": { + "labeled_cases": 0, + "correct_cases": 0 + }, + "execution_state_eval": { + "checks_total": 2, + "checks_passed": 2 + }, + "route_distribution": { + "store_feature_risk": 1, + "hybrid_store_plus_live": 1 + }, + "fallback_distribution": { + "none": 2 + }, + "results": [ + { + "case_id": "BQ-001", + "raw_question": "Проверь счет 60 за июнь 2020", + "validation_passed": true, + "message_in_scope": true, + "scope_confidence": "high", + "contains_multiple_tasks": false, + "fragments_total": 1, + "in_scope_fragments": 1, + "out_of_scope_fragments": 0, + "unclear_fragments": 0, + "fallback_type": "none", + "predicted_route_status": "routed", + "expected_route_status": null, + "predicted_no_route_reason": null, + "expected_no_route_reason": null, + "predicted_clarification_required": false, + "expected_clarification_required": null, + "executable_with_soft_assumptions_fragments": 1, + "trace_id": "0XdpLLt2DVEC8b", + "request_count_for_case": 0 + }, + { + "case_id": "BQ-002", + "raw_question": "Покажи риски по НДС и по закрытию", + "validation_passed": true, + "message_in_scope": true, + "scope_confidence": "high", + "contains_multiple_tasks": false, + "fragments_total": 1, + "in_scope_fragments": 1, + "out_of_scope_fragments": 0, + "unclear_fragments": 0, + "fallback_type": "none", + "predicted_route_status": "routed", + "expected_route_status": null, + "predicted_no_route_reason": null, + "expected_no_route_reason": null, + "predicted_clarification_required": false, + "expected_clarification_required": null, + "executable_with_soft_assumptions_fragments": 1, + "trace_id": "TGXTmJEIbfRfxl", + "request_count_for_case": 0 + } + ] +} \ No newline at end of file diff --git a/llm_normalizer/data/eval_cases/eval-EYDYh4k78m.report.json b/llm_normalizer/data/eval_cases/eval-EYDYh4k78m.report.json new file mode 100644 index 0000000..baa11d1 --- /dev/null +++ b/llm_normalizer/data/eval_cases/eval-EYDYh4k78m.report.json @@ -0,0 +1,137 @@ +{ + "run_id": "eval-EYDYh4k78m", + "timestamp": "2026-04-11T10:35:23.070Z", + "mode": "single-pass-strict", + "use_mock": true, + "prompt_version": "normalizer_v2_0_2", + "schema_version": "v2_0_2", + "dataset": { + "source": "inline_raw_questions", + "file": null, + "raw_questions_count": 3 + }, + "cases_total": 3, + "metrics": { + "schema_validation_pass_rate": 100, + "scope_detection_accuracy": null, + "scope_in_scope_rate": 33.33, + "multi_intent_detected_rate": 0, + "clarification_required_rate": 0, + "avg_fragments_per_message": 1, + "out_of_scope_fragment_rate": 33.33, + "routed_fragment_rate": 66.67, + "no_route_fragment_rate": 33.33, + "route_resolution_accuracy": null, + "no_route_precision": null, + "false_no_route_rate": null, + "execution_state_consistency_rate": 66.67, + "executable_with_soft_assumptions_rate": 100, + "soft_assumption_used_fragment_rate": 100, + "clarification_precision": null, + "clarification_recall": null, + "false_clarification_rate": null + }, + "budget": { + "requests_total": 0, + "retries_used": 0 + }, + "clarification_eval": { + "labeled_cases": 0, + "true_positive": 0, + "false_positive": 0, + "false_negative": 0 + }, + "route_eval": { + "labeled_cases": 0, + "correct_cases": 0, + "expected_routed_cases": 0, + "no_route_true_positive": 0, + "no_route_false_positive": 0 + }, + "scope_eval": { + "labeled_cases": 0, + "correct_cases": 0 + }, + "execution_state_eval": { + "checks_total": 3, + "checks_passed": 2 + }, + "route_distribution": { + "hybrid_store_plus_live": 1, + "no_route": 1, + "batch_refresh_then_store": 1 + }, + "fallback_distribution": { + "none": 1, + "out_of_scope": 1, + "clarification": 1 + }, + "results": [ + { + "case_id": "BQ-001", + "raw_question": "Проверь хвосты по поставщикам и разложи цепочку", + "validation_passed": true, + "message_in_scope": true, + "scope_confidence": "high", + "contains_multiple_tasks": false, + "fragments_total": 1, + "in_scope_fragments": 1, + "out_of_scope_fragments": 0, + "unclear_fragments": 0, + "fallback_type": "none", + "predicted_route_status": "routed", + "expected_route_status": null, + "predicted_no_route_reason": null, + "expected_no_route_reason": null, + "predicted_clarification_required": false, + "expected_clarification_required": null, + "executable_with_soft_assumptions_fragments": 1, + "trace_id": "XkM4LP-bXu4rf9", + "request_count_for_case": 0 + }, + { + "case_id": "BQ-002", + "raw_question": "Как вообще по ФСБУ", + "validation_passed": true, + "message_in_scope": false, + "scope_confidence": "low", + "contains_multiple_tasks": false, + "fragments_total": 1, + "in_scope_fragments": 0, + "out_of_scope_fragments": 1, + "unclear_fragments": 0, + "fallback_type": "out_of_scope", + "predicted_route_status": "no_route", + "expected_route_status": null, + "predicted_no_route_reason": "out_of_scope", + "expected_no_route_reason": null, + "predicted_clarification_required": false, + "expected_clarification_required": null, + "executable_with_soft_assumptions_fragments": 0, + "trace_id": "eDF6_4JOsguyhk", + "request_count_for_case": 0 + }, + { + "case_id": "BQ-003", + "raw_question": "Покажи топ рисков за июнь 2020", + "validation_passed": true, + "message_in_scope": false, + "scope_confidence": "low", + "contains_multiple_tasks": false, + "fragments_total": 1, + "in_scope_fragments": 0, + "out_of_scope_fragments": 0, + "unclear_fragments": 1, + "fallback_type": "clarification", + "predicted_route_status": "routed", + "expected_route_status": null, + "predicted_no_route_reason": null, + "expected_no_route_reason": null, + "predicted_clarification_required": false, + "expected_clarification_required": null, + "executable_with_soft_assumptions_fragments": 0, + "trace_id": "dsCVkLkLYqwqHr", + "request_count_for_case": 0 + } + ] +} \ No newline at end of file diff --git a/llm_normalizer/data/eval_cases/eval-NeqPDTflc7.report.json b/llm_normalizer/data/eval_cases/eval-NeqPDTflc7.report.json new file mode 100644 index 0000000..68c37be --- /dev/null +++ b/llm_normalizer/data/eval_cases/eval-NeqPDTflc7.report.json @@ -0,0 +1,112 @@ +{ + "run_id": "eval-NeqPDTflc7", + "timestamp": "2026-04-11T10:16:53.909Z", + "mode": "single-pass-strict", + "use_mock": true, + "prompt_version": "normalizer_v2_0_2", + "schema_version": "v2_0_2", + "dataset": { + "source": "inline_raw_questions", + "file": null, + "raw_questions_count": 2 + }, + "cases_total": 2, + "metrics": { + "schema_validation_pass_rate": 100, + "scope_detection_accuracy": null, + "scope_in_scope_rate": 100, + "multi_intent_detected_rate": 0, + "clarification_required_rate": 0, + "avg_fragments_per_message": 1, + "out_of_scope_fragment_rate": 0, + "routed_fragment_rate": 100, + "no_route_fragment_rate": 0, + "route_resolution_accuracy": null, + "no_route_precision": null, + "false_no_route_rate": null, + "execution_state_consistency_rate": 100, + "executable_with_soft_assumptions_rate": 100, + "soft_assumption_used_fragment_rate": 100, + "clarification_precision": null, + "clarification_recall": null, + "false_clarification_rate": null + }, + "budget": { + "requests_total": 0, + "retries_used": 0 + }, + "clarification_eval": { + "labeled_cases": 0, + "true_positive": 0, + "false_positive": 0, + "false_negative": 0 + }, + "route_eval": { + "labeled_cases": 0, + "correct_cases": 0, + "expected_routed_cases": 0, + "no_route_true_positive": 0, + "no_route_false_positive": 0 + }, + "scope_eval": { + "labeled_cases": 0, + "correct_cases": 0 + }, + "execution_state_eval": { + "checks_total": 2, + "checks_passed": 2 + }, + "route_distribution": { + "store_feature_risk": 1, + "hybrid_store_plus_live": 1 + }, + "fallback_distribution": { + "none": 2 + }, + "results": [ + { + "case_id": "BQ-001", + "raw_question": "Проверь счет 60 за июнь 2020", + "validation_passed": true, + "message_in_scope": true, + "scope_confidence": "high", + "contains_multiple_tasks": false, + "fragments_total": 1, + "in_scope_fragments": 1, + "out_of_scope_fragments": 0, + "unclear_fragments": 0, + "fallback_type": "none", + "predicted_route_status": "routed", + "expected_route_status": null, + "predicted_no_route_reason": null, + "expected_no_route_reason": null, + "predicted_clarification_required": false, + "expected_clarification_required": null, + "executable_with_soft_assumptions_fragments": 1, + "trace_id": "ynDJfmhtaBS6Jh", + "request_count_for_case": 0 + }, + { + "case_id": "BQ-002", + "raw_question": "Покажи риски по счету 97", + "validation_passed": true, + "message_in_scope": true, + "scope_confidence": "high", + "contains_multiple_tasks": false, + "fragments_total": 1, + "in_scope_fragments": 1, + "out_of_scope_fragments": 0, + "unclear_fragments": 0, + "fallback_type": "none", + "predicted_route_status": "routed", + "expected_route_status": null, + "predicted_no_route_reason": null, + "expected_no_route_reason": null, + "predicted_clarification_required": false, + "expected_clarification_required": null, + "executable_with_soft_assumptions_fragments": 1, + "trace_id": "BhT9NfO-40oigp", + "request_count_for_case": 0 + } + ] +} \ No newline at end of file diff --git a/llm_normalizer/data/eval_cases/eval-OSNnoiu9KQ.report.json b/llm_normalizer/data/eval_cases/eval-OSNnoiu9KQ.report.json new file mode 100644 index 0000000..065f03c --- /dev/null +++ b/llm_normalizer/data/eval_cases/eval-OSNnoiu9KQ.report.json @@ -0,0 +1,137 @@ +{ + "run_id": "eval-OSNnoiu9KQ", + "timestamp": "2026-04-11T10:16:34.741Z", + "mode": "single-pass-strict", + "use_mock": true, + "prompt_version": "normalizer_v2_0_2", + "schema_version": "v2_0_2", + "dataset": { + "source": "inline_raw_questions", + "file": null, + "raw_questions_count": 3 + }, + "cases_total": 3, + "metrics": { + "schema_validation_pass_rate": 100, + "scope_detection_accuracy": null, + "scope_in_scope_rate": 33.33, + "multi_intent_detected_rate": 0, + "clarification_required_rate": 0, + "avg_fragments_per_message": 1, + "out_of_scope_fragment_rate": 33.33, + "routed_fragment_rate": 66.67, + "no_route_fragment_rate": 33.33, + "route_resolution_accuracy": null, + "no_route_precision": null, + "false_no_route_rate": null, + "execution_state_consistency_rate": 66.67, + "executable_with_soft_assumptions_rate": 100, + "soft_assumption_used_fragment_rate": 100, + "clarification_precision": null, + "clarification_recall": null, + "false_clarification_rate": null + }, + "budget": { + "requests_total": 0, + "retries_used": 0 + }, + "clarification_eval": { + "labeled_cases": 0, + "true_positive": 0, + "false_positive": 0, + "false_negative": 0 + }, + "route_eval": { + "labeled_cases": 0, + "correct_cases": 0, + "expected_routed_cases": 0, + "no_route_true_positive": 0, + "no_route_false_positive": 0 + }, + "scope_eval": { + "labeled_cases": 0, + "correct_cases": 0 + }, + "execution_state_eval": { + "checks_total": 3, + "checks_passed": 2 + }, + "route_distribution": { + "hybrid_store_plus_live": 1, + "no_route": 1, + "batch_refresh_then_store": 1 + }, + "fallback_distribution": { + "none": 1, + "out_of_scope": 1, + "clarification": 1 + }, + "results": [ + { + "case_id": "BQ-001", + "raw_question": "Проверь хвосты по поставщикам и разложи цепочку", + "validation_passed": true, + "message_in_scope": true, + "scope_confidence": "high", + "contains_multiple_tasks": false, + "fragments_total": 1, + "in_scope_fragments": 1, + "out_of_scope_fragments": 0, + "unclear_fragments": 0, + "fallback_type": "none", + "predicted_route_status": "routed", + "expected_route_status": null, + "predicted_no_route_reason": null, + "expected_no_route_reason": null, + "predicted_clarification_required": false, + "expected_clarification_required": null, + "executable_with_soft_assumptions_fragments": 1, + "trace_id": "YPmWhiLGA674vn", + "request_count_for_case": 0 + }, + { + "case_id": "BQ-002", + "raw_question": "Как вообще по ФСБУ", + "validation_passed": true, + "message_in_scope": false, + "scope_confidence": "low", + "contains_multiple_tasks": false, + "fragments_total": 1, + "in_scope_fragments": 0, + "out_of_scope_fragments": 1, + "unclear_fragments": 0, + "fallback_type": "out_of_scope", + "predicted_route_status": "no_route", + "expected_route_status": null, + "predicted_no_route_reason": "out_of_scope", + "expected_no_route_reason": null, + "predicted_clarification_required": false, + "expected_clarification_required": null, + "executable_with_soft_assumptions_fragments": 0, + "trace_id": "JAbihOWvYs9bYR", + "request_count_for_case": 0 + }, + { + "case_id": "BQ-003", + "raw_question": "Покажи топ рисков за июнь 2020", + "validation_passed": true, + "message_in_scope": false, + "scope_confidence": "low", + "contains_multiple_tasks": false, + "fragments_total": 1, + "in_scope_fragments": 0, + "out_of_scope_fragments": 0, + "unclear_fragments": 1, + "fallback_type": "clarification", + "predicted_route_status": "routed", + "expected_route_status": null, + "predicted_no_route_reason": null, + "expected_no_route_reason": null, + "predicted_clarification_required": false, + "expected_clarification_required": null, + "executable_with_soft_assumptions_fragments": 0, + "trace_id": "WuI3XbextvaDxw", + "request_count_for_case": 0 + } + ] +} \ No newline at end of file diff --git a/llm_normalizer/data/eval_cases/eval-RVeDpGREWm.report.json b/llm_normalizer/data/eval_cases/eval-RVeDpGREWm.report.json new file mode 100644 index 0000000..99dbd05 --- /dev/null +++ b/llm_normalizer/data/eval_cases/eval-RVeDpGREWm.report.json @@ -0,0 +1,112 @@ +{ + "run_id": "eval-RVeDpGREWm", + "timestamp": "2026-04-11T10:14:44.794Z", + "mode": "single-pass-strict", + "use_mock": true, + "prompt_version": "normalizer_v2_0_2", + "schema_version": "v2_0_2", + "dataset": { + "source": "inline_raw_questions", + "file": null, + "raw_questions_count": 2 + }, + "cases_total": 2, + "metrics": { + "schema_validation_pass_rate": 100, + "scope_detection_accuracy": null, + "scope_in_scope_rate": 100, + "multi_intent_detected_rate": 0, + "clarification_required_rate": 0, + "avg_fragments_per_message": 1, + "out_of_scope_fragment_rate": 0, + "routed_fragment_rate": 100, + "no_route_fragment_rate": 0, + "route_resolution_accuracy": null, + "no_route_precision": null, + "false_no_route_rate": null, + "execution_state_consistency_rate": 100, + "executable_with_soft_assumptions_rate": 100, + "soft_assumption_used_fragment_rate": 100, + "clarification_precision": null, + "clarification_recall": null, + "false_clarification_rate": null + }, + "budget": { + "requests_total": 0, + "retries_used": 0 + }, + "clarification_eval": { + "labeled_cases": 0, + "true_positive": 0, + "false_positive": 0, + "false_negative": 0 + }, + "route_eval": { + "labeled_cases": 0, + "correct_cases": 0, + "expected_routed_cases": 0, + "no_route_true_positive": 0, + "no_route_false_positive": 0 + }, + "scope_eval": { + "labeled_cases": 0, + "correct_cases": 0 + }, + "execution_state_eval": { + "checks_total": 2, + "checks_passed": 2 + }, + "route_distribution": { + "store_feature_risk": 1, + "hybrid_store_plus_live": 1 + }, + "fallback_distribution": { + "none": 2 + }, + "results": [ + { + "case_id": "BQ-001", + "raw_question": "Проверь счет 60 за июнь 2020", + "validation_passed": true, + "message_in_scope": true, + "scope_confidence": "high", + "contains_multiple_tasks": false, + "fragments_total": 1, + "in_scope_fragments": 1, + "out_of_scope_fragments": 0, + "unclear_fragments": 0, + "fallback_type": "none", + "predicted_route_status": "routed", + "expected_route_status": null, + "predicted_no_route_reason": null, + "expected_no_route_reason": null, + "predicted_clarification_required": false, + "expected_clarification_required": null, + "executable_with_soft_assumptions_fragments": 1, + "trace_id": "9WDoQo0uvKHsFh", + "request_count_for_case": 0 + }, + { + "case_id": "BQ-002", + "raw_question": "Покажи риски по НДС и по закрытию", + "validation_passed": true, + "message_in_scope": true, + "scope_confidence": "high", + "contains_multiple_tasks": false, + "fragments_total": 1, + "in_scope_fragments": 1, + "out_of_scope_fragments": 0, + "unclear_fragments": 0, + "fallback_type": "none", + "predicted_route_status": "routed", + "expected_route_status": null, + "predicted_no_route_reason": null, + "expected_no_route_reason": null, + "predicted_clarification_required": false, + "expected_clarification_required": null, + "executable_with_soft_assumptions_fragments": 1, + "trace_id": "YJ7f6z9_SS7ZgW", + "request_count_for_case": 0 + } + ] +} \ No newline at end of file diff --git a/llm_normalizer/data/eval_cases/eval-hhXvDmFzGJ.report.json b/llm_normalizer/data/eval_cases/eval-hhXvDmFzGJ.report.json new file mode 100644 index 0000000..f096c0d --- /dev/null +++ b/llm_normalizer/data/eval_cases/eval-hhXvDmFzGJ.report.json @@ -0,0 +1,137 @@ +{ + "run_id": "eval-hhXvDmFzGJ", + "timestamp": "2026-04-11T10:14:25.501Z", + "mode": "single-pass-strict", + "use_mock": true, + "prompt_version": "normalizer_v2_0_2", + "schema_version": "v2_0_2", + "dataset": { + "source": "inline_raw_questions", + "file": null, + "raw_questions_count": 3 + }, + "cases_total": 3, + "metrics": { + "schema_validation_pass_rate": 100, + "scope_detection_accuracy": null, + "scope_in_scope_rate": 33.33, + "multi_intent_detected_rate": 0, + "clarification_required_rate": 0, + "avg_fragments_per_message": 1, + "out_of_scope_fragment_rate": 33.33, + "routed_fragment_rate": 66.67, + "no_route_fragment_rate": 33.33, + "route_resolution_accuracy": null, + "no_route_precision": null, + "false_no_route_rate": null, + "execution_state_consistency_rate": 66.67, + "executable_with_soft_assumptions_rate": 100, + "soft_assumption_used_fragment_rate": 100, + "clarification_precision": null, + "clarification_recall": null, + "false_clarification_rate": null + }, + "budget": { + "requests_total": 0, + "retries_used": 0 + }, + "clarification_eval": { + "labeled_cases": 0, + "true_positive": 0, + "false_positive": 0, + "false_negative": 0 + }, + "route_eval": { + "labeled_cases": 0, + "correct_cases": 0, + "expected_routed_cases": 0, + "no_route_true_positive": 0, + "no_route_false_positive": 0 + }, + "scope_eval": { + "labeled_cases": 0, + "correct_cases": 0 + }, + "execution_state_eval": { + "checks_total": 3, + "checks_passed": 2 + }, + "route_distribution": { + "hybrid_store_plus_live": 1, + "no_route": 1, + "batch_refresh_then_store": 1 + }, + "fallback_distribution": { + "none": 1, + "out_of_scope": 1, + "clarification": 1 + }, + "results": [ + { + "case_id": "BQ-001", + "raw_question": "Проверь хвосты по поставщикам и разложи цепочку", + "validation_passed": true, + "message_in_scope": true, + "scope_confidence": "high", + "contains_multiple_tasks": false, + "fragments_total": 1, + "in_scope_fragments": 1, + "out_of_scope_fragments": 0, + "unclear_fragments": 0, + "fallback_type": "none", + "predicted_route_status": "routed", + "expected_route_status": null, + "predicted_no_route_reason": null, + "expected_no_route_reason": null, + "predicted_clarification_required": false, + "expected_clarification_required": null, + "executable_with_soft_assumptions_fragments": 1, + "trace_id": "5-MShsMwdLMm1O", + "request_count_for_case": 0 + }, + { + "case_id": "BQ-002", + "raw_question": "Как вообще по ФСБУ", + "validation_passed": true, + "message_in_scope": false, + "scope_confidence": "low", + "contains_multiple_tasks": false, + "fragments_total": 1, + "in_scope_fragments": 0, + "out_of_scope_fragments": 1, + "unclear_fragments": 0, + "fallback_type": "out_of_scope", + "predicted_route_status": "no_route", + "expected_route_status": null, + "predicted_no_route_reason": "out_of_scope", + "expected_no_route_reason": null, + "predicted_clarification_required": false, + "expected_clarification_required": null, + "executable_with_soft_assumptions_fragments": 0, + "trace_id": "pv-o-6Cock8Ve2", + "request_count_for_case": 0 + }, + { + "case_id": "BQ-003", + "raw_question": "Покажи топ рисков за июнь 2020", + "validation_passed": true, + "message_in_scope": false, + "scope_confidence": "low", + "contains_multiple_tasks": false, + "fragments_total": 1, + "in_scope_fragments": 0, + "out_of_scope_fragments": 0, + "unclear_fragments": 1, + "fallback_type": "clarification", + "predicted_route_status": "routed", + "expected_route_status": null, + "predicted_no_route_reason": null, + "expected_no_route_reason": null, + "predicted_clarification_required": false, + "expected_clarification_required": null, + "executable_with_soft_assumptions_fragments": 0, + "trace_id": "K0zAFkzMAu2BqF", + "request_count_for_case": 0 + } + ] +} \ No newline at end of file diff --git a/llm_normalizer/data/eval_cases/eval-kBTYkPR4wq.report.json b/llm_normalizer/data/eval_cases/eval-kBTYkPR4wq.report.json new file mode 100644 index 0000000..d258bf7 --- /dev/null +++ b/llm_normalizer/data/eval_cases/eval-kBTYkPR4wq.report.json @@ -0,0 +1,112 @@ +{ + "run_id": "eval-kBTYkPR4wq", + "timestamp": "2026-04-11T10:16:53.895Z", + "mode": "single-pass-strict", + "use_mock": true, + "prompt_version": "normalizer_v2_0_2", + "schema_version": "v2_0_2", + "dataset": { + "source": "inline_raw_questions", + "file": null, + "raw_questions_count": 2 + }, + "cases_total": 2, + "metrics": { + "schema_validation_pass_rate": 100, + "scope_detection_accuracy": null, + "scope_in_scope_rate": 100, + "multi_intent_detected_rate": 0, + "clarification_required_rate": 0, + "avg_fragments_per_message": 1, + "out_of_scope_fragment_rate": 0, + "routed_fragment_rate": 100, + "no_route_fragment_rate": 0, + "route_resolution_accuracy": null, + "no_route_precision": null, + "false_no_route_rate": null, + "execution_state_consistency_rate": 100, + "executable_with_soft_assumptions_rate": 100, + "soft_assumption_used_fragment_rate": 100, + "clarification_precision": null, + "clarification_recall": null, + "false_clarification_rate": null + }, + "budget": { + "requests_total": 0, + "retries_used": 0 + }, + "clarification_eval": { + "labeled_cases": 0, + "true_positive": 0, + "false_positive": 0, + "false_negative": 0 + }, + "route_eval": { + "labeled_cases": 0, + "correct_cases": 0, + "expected_routed_cases": 0, + "no_route_true_positive": 0, + "no_route_false_positive": 0 + }, + "scope_eval": { + "labeled_cases": 0, + "correct_cases": 0 + }, + "execution_state_eval": { + "checks_total": 2, + "checks_passed": 2 + }, + "route_distribution": { + "store_feature_risk": 1, + "hybrid_store_plus_live": 1 + }, + "fallback_distribution": { + "none": 2 + }, + "results": [ + { + "case_id": "BQ-001", + "raw_question": "Проверь счет 60 за июнь 2020", + "validation_passed": true, + "message_in_scope": true, + "scope_confidence": "high", + "contains_multiple_tasks": false, + "fragments_total": 1, + "in_scope_fragments": 1, + "out_of_scope_fragments": 0, + "unclear_fragments": 0, + "fallback_type": "none", + "predicted_route_status": "routed", + "expected_route_status": null, + "predicted_no_route_reason": null, + "expected_no_route_reason": null, + "predicted_clarification_required": false, + "expected_clarification_required": null, + "executable_with_soft_assumptions_fragments": 1, + "trace_id": "ZQ4J6HgngY7JB4", + "request_count_for_case": 0 + }, + { + "case_id": "BQ-002", + "raw_question": "Покажи риски по НДС и по закрытию", + "validation_passed": true, + "message_in_scope": true, + "scope_confidence": "high", + "contains_multiple_tasks": false, + "fragments_total": 1, + "in_scope_fragments": 1, + "out_of_scope_fragments": 0, + "unclear_fragments": 0, + "fallback_type": "none", + "predicted_route_status": "routed", + "expected_route_status": null, + "predicted_no_route_reason": null, + "expected_no_route_reason": null, + "predicted_clarification_required": false, + "expected_clarification_required": null, + "executable_with_soft_assumptions_fragments": 1, + "trace_id": "Vk2rIlI-UGAuAE", + "request_count_for_case": 0 + } + ] +} \ No newline at end of file diff --git a/llm_normalizer/data/eval_cases/eval-nL2h6Z0kKG.report.json b/llm_normalizer/data/eval_cases/eval-nL2h6Z0kKG.report.json new file mode 100644 index 0000000..60ce3c0 --- /dev/null +++ b/llm_normalizer/data/eval_cases/eval-nL2h6Z0kKG.report.json @@ -0,0 +1,112 @@ +{ + "run_id": "eval-nL2h6Z0kKG", + "timestamp": "2026-04-11T10:35:37.559Z", + "mode": "single-pass-strict", + "use_mock": true, + "prompt_version": "normalizer_v2_0_2", + "schema_version": "v2_0_2", + "dataset": { + "source": "inline_raw_questions", + "file": null, + "raw_questions_count": 2 + }, + "cases_total": 2, + "metrics": { + "schema_validation_pass_rate": 100, + "scope_detection_accuracy": null, + "scope_in_scope_rate": 100, + "multi_intent_detected_rate": 0, + "clarification_required_rate": 0, + "avg_fragments_per_message": 1, + "out_of_scope_fragment_rate": 0, + "routed_fragment_rate": 100, + "no_route_fragment_rate": 0, + "route_resolution_accuracy": null, + "no_route_precision": null, + "false_no_route_rate": null, + "execution_state_consistency_rate": 100, + "executable_with_soft_assumptions_rate": 100, + "soft_assumption_used_fragment_rate": 100, + "clarification_precision": null, + "clarification_recall": null, + "false_clarification_rate": null + }, + "budget": { + "requests_total": 0, + "retries_used": 0 + }, + "clarification_eval": { + "labeled_cases": 0, + "true_positive": 0, + "false_positive": 0, + "false_negative": 0 + }, + "route_eval": { + "labeled_cases": 0, + "correct_cases": 0, + "expected_routed_cases": 0, + "no_route_true_positive": 0, + "no_route_false_positive": 0 + }, + "scope_eval": { + "labeled_cases": 0, + "correct_cases": 0 + }, + "execution_state_eval": { + "checks_total": 2, + "checks_passed": 2 + }, + "route_distribution": { + "store_feature_risk": 1, + "hybrid_store_plus_live": 1 + }, + "fallback_distribution": { + "none": 2 + }, + "results": [ + { + "case_id": "BQ-001", + "raw_question": "Проверь счет 60 за июнь 2020", + "validation_passed": true, + "message_in_scope": true, + "scope_confidence": "high", + "contains_multiple_tasks": false, + "fragments_total": 1, + "in_scope_fragments": 1, + "out_of_scope_fragments": 0, + "unclear_fragments": 0, + "fallback_type": "none", + "predicted_route_status": "routed", + "expected_route_status": null, + "predicted_no_route_reason": null, + "expected_no_route_reason": null, + "predicted_clarification_required": false, + "expected_clarification_required": null, + "executable_with_soft_assumptions_fragments": 1, + "trace_id": "gKYkJDhEWkCQTw", + "request_count_for_case": 0 + }, + { + "case_id": "BQ-002", + "raw_question": "Покажи риски по счету 97", + "validation_passed": true, + "message_in_scope": true, + "scope_confidence": "high", + "contains_multiple_tasks": false, + "fragments_total": 1, + "in_scope_fragments": 1, + "out_of_scope_fragments": 0, + "unclear_fragments": 0, + "fallback_type": "none", + "predicted_route_status": "routed", + "expected_route_status": null, + "predicted_no_route_reason": null, + "expected_no_route_reason": null, + "predicted_clarification_required": false, + "expected_clarification_required": null, + "executable_with_soft_assumptions_fragments": 1, + "trace_id": "YDK8VaP88Tx8dy", + "request_count_for_case": 0 + } + ] +} \ No newline at end of file diff --git a/llm_normalizer/data/eval_cases/eval-qYzl2S0IV9.report.json b/llm_normalizer/data/eval_cases/eval-qYzl2S0IV9.report.json new file mode 100644 index 0000000..bb5599e --- /dev/null +++ b/llm_normalizer/data/eval_cases/eval-qYzl2S0IV9.report.json @@ -0,0 +1,112 @@ +{ + "run_id": "eval-qYzl2S0IV9", + "timestamp": "2026-04-11T10:37:58.754Z", + "mode": "single-pass-strict", + "use_mock": true, + "prompt_version": "normalizer_v2_0_2", + "schema_version": "v2_0_2", + "dataset": { + "source": "inline_raw_questions", + "file": null, + "raw_questions_count": 2 + }, + "cases_total": 2, + "metrics": { + "schema_validation_pass_rate": 100, + "scope_detection_accuracy": null, + "scope_in_scope_rate": 100, + "multi_intent_detected_rate": 0, + "clarification_required_rate": 0, + "avg_fragments_per_message": 1, + "out_of_scope_fragment_rate": 0, + "routed_fragment_rate": 100, + "no_route_fragment_rate": 0, + "route_resolution_accuracy": null, + "no_route_precision": null, + "false_no_route_rate": null, + "execution_state_consistency_rate": 100, + "executable_with_soft_assumptions_rate": 100, + "soft_assumption_used_fragment_rate": 100, + "clarification_precision": null, + "clarification_recall": null, + "false_clarification_rate": null + }, + "budget": { + "requests_total": 0, + "retries_used": 0 + }, + "clarification_eval": { + "labeled_cases": 0, + "true_positive": 0, + "false_positive": 0, + "false_negative": 0 + }, + "route_eval": { + "labeled_cases": 0, + "correct_cases": 0, + "expected_routed_cases": 0, + "no_route_true_positive": 0, + "no_route_false_positive": 0 + }, + "scope_eval": { + "labeled_cases": 0, + "correct_cases": 0 + }, + "execution_state_eval": { + "checks_total": 2, + "checks_passed": 2 + }, + "route_distribution": { + "store_feature_risk": 1, + "hybrid_store_plus_live": 1 + }, + "fallback_distribution": { + "none": 2 + }, + "results": [ + { + "case_id": "BQ-001", + "raw_question": "Проверь счет 60 за июнь 2020", + "validation_passed": true, + "message_in_scope": true, + "scope_confidence": "high", + "contains_multiple_tasks": false, + "fragments_total": 1, + "in_scope_fragments": 1, + "out_of_scope_fragments": 0, + "unclear_fragments": 0, + "fallback_type": "none", + "predicted_route_status": "routed", + "expected_route_status": null, + "predicted_no_route_reason": null, + "expected_no_route_reason": null, + "predicted_clarification_required": false, + "expected_clarification_required": null, + "executable_with_soft_assumptions_fragments": 1, + "trace_id": "3a_NZFB9MhKiKT", + "request_count_for_case": 0 + }, + { + "case_id": "BQ-002", + "raw_question": "Покажи риски по счету 97", + "validation_passed": true, + "message_in_scope": true, + "scope_confidence": "high", + "contains_multiple_tasks": false, + "fragments_total": 1, + "in_scope_fragments": 1, + "out_of_scope_fragments": 0, + "unclear_fragments": 0, + "fallback_type": "none", + "predicted_route_status": "routed", + "expected_route_status": null, + "predicted_no_route_reason": null, + "expected_no_route_reason": null, + "predicted_clarification_required": false, + "expected_clarification_required": null, + "executable_with_soft_assumptions_fragments": 1, + "trace_id": "BrD8ORrgm8qsAy", + "request_count_for_case": 0 + } + ] +} \ No newline at end of file diff --git a/llm_normalizer/data/eval_cases/eval-wWlVBoabZW.report.json b/llm_normalizer/data/eval_cases/eval-wWlVBoabZW.report.json new file mode 100644 index 0000000..5698a0e --- /dev/null +++ b/llm_normalizer/data/eval_cases/eval-wWlVBoabZW.report.json @@ -0,0 +1,112 @@ +{ + "run_id": "eval-wWlVBoabZW", + "timestamp": "2026-04-11T10:14:44.777Z", + "mode": "single-pass-strict", + "use_mock": true, + "prompt_version": "normalizer_v2_0_2", + "schema_version": "v2_0_2", + "dataset": { + "source": "inline_raw_questions", + "file": null, + "raw_questions_count": 2 + }, + "cases_total": 2, + "metrics": { + "schema_validation_pass_rate": 100, + "scope_detection_accuracy": null, + "scope_in_scope_rate": 100, + "multi_intent_detected_rate": 0, + "clarification_required_rate": 0, + "avg_fragments_per_message": 1, + "out_of_scope_fragment_rate": 0, + "routed_fragment_rate": 100, + "no_route_fragment_rate": 0, + "route_resolution_accuracy": null, + "no_route_precision": null, + "false_no_route_rate": null, + "execution_state_consistency_rate": 100, + "executable_with_soft_assumptions_rate": 100, + "soft_assumption_used_fragment_rate": 100, + "clarification_precision": null, + "clarification_recall": null, + "false_clarification_rate": null + }, + "budget": { + "requests_total": 0, + "retries_used": 0 + }, + "clarification_eval": { + "labeled_cases": 0, + "true_positive": 0, + "false_positive": 0, + "false_negative": 0 + }, + "route_eval": { + "labeled_cases": 0, + "correct_cases": 0, + "expected_routed_cases": 0, + "no_route_true_positive": 0, + "no_route_false_positive": 0 + }, + "scope_eval": { + "labeled_cases": 0, + "correct_cases": 0 + }, + "execution_state_eval": { + "checks_total": 2, + "checks_passed": 2 + }, + "route_distribution": { + "store_feature_risk": 1, + "hybrid_store_plus_live": 1 + }, + "fallback_distribution": { + "none": 2 + }, + "results": [ + { + "case_id": "BQ-001", + "raw_question": "Проверь счет 60 за июнь 2020", + "validation_passed": true, + "message_in_scope": true, + "scope_confidence": "high", + "contains_multiple_tasks": false, + "fragments_total": 1, + "in_scope_fragments": 1, + "out_of_scope_fragments": 0, + "unclear_fragments": 0, + "fallback_type": "none", + "predicted_route_status": "routed", + "expected_route_status": null, + "predicted_no_route_reason": null, + "expected_no_route_reason": null, + "predicted_clarification_required": false, + "expected_clarification_required": null, + "executable_with_soft_assumptions_fragments": 1, + "trace_id": "3CW7yHQOH32rKS", + "request_count_for_case": 0 + }, + { + "case_id": "BQ-002", + "raw_question": "Покажи риски по счету 97", + "validation_passed": true, + "message_in_scope": true, + "scope_confidence": "high", + "contains_multiple_tasks": false, + "fragments_total": 1, + "in_scope_fragments": 1, + "out_of_scope_fragments": 0, + "unclear_fragments": 0, + "fallback_type": "none", + "predicted_route_status": "routed", + "expected_route_status": null, + "predicted_no_route_reason": null, + "expected_no_route_reason": null, + "predicted_clarification_required": false, + "expected_clarification_required": null, + "executable_with_soft_assumptions_fragments": 1, + "trace_id": "Gdw6ytd-K55hUm", + "request_count_for_case": 0 + } + ] +} \ No newline at end of file diff --git a/tmp_llm_gate_log.txt b/tmp_llm_gate_log.txt new file mode 100644 index 0000000000000000000000000000000000000000..d824960288f5856e93ea36ff98a55011523add27 GIT binary patch literal 37422 zcmeI5*>Y7^ddK&Lu2PkouB1|xl$~RIVVtx82?>N4jKCPvrg5k3q~j)zirIug1PL%n z$U`I#(vOq3N%H@#|M|4m+S54_;6^U$)S32P!#7WB?Y;l+fB&@kljdAAX&&nJs99_t zH(Sk9{koz5_nUuf?&#lQb5s9sH4pUfadW#l-yCa>G)sCPQ_me8-PUJ}^j!Vo*hIab zsZVaT-5k|e+j`wky>962PP3s=Z>udMZ8ujFEWb(rZ|m4C!StwkqR(ypJF+`EzqU2@ zqP{1ZhqL@QE)(@*^ew&br{52C&c|-+$Zeek&Pjr2(%jqq4{Z0;3mPyw;~U3sb>@+N zZ)vuj=4^9Z6z~h|Z=1hwuIbyyPEF4)H_PcPM~|nL&-Hyo zM~|qdTOV(t^(oEusQJfcT{K*3F6#4I^SQn^r~i!iX2QA6!=o)8dPYVLsQLVjJ#G$cXH!6wR6h4gdP_zm@Z)%hW znmtCg^uT*0=8F0ocf+(Jte*@>t|clMBZd*7ZKQaCu=(zt$Ee&HBQ*g)F8Pg=ZK;3obB;L8-}aqc+XO+z7fzw>??f6TL8=JNKT&xz$4ufJhs8$$!t($Q^)y+ zXLu;^elBeTYHN`D;mnQ!a`z0UkJj!{#a$k=hHM{_6K^?2dSIYYu=f$ z4^K7fW69~JV1$p*sI-+Fhjz9deL9r;p&N{du07XCSohguS>~~=;DtXz1Hct}2QEPH zqekzCryir9TV0D+QW}kI>mEMJ^W707@S>gv%5a8}9i6;P_-^Y+jrZQiMru5!A-JXg zrKX@wj^(;|JxuUe)@q3Rye?R@N5|LM7mtk&zxqb(w~^hEY8u@Tb>T7|=%M_wQum$6-GxX86)Vy#kG|RGLN$TkOeZ2oV zQCrtST#-bexlfb!5SdMs<^M)`)kK#5PV-XV)*`GeHte?i9eKo-`oX`&bo6f;UR$Zp zW69#A`A+|y>D!t7Bxxa4iHXMK%v1ep&xGzyWW9;^pNR8h&`0$P&$Xiwfb)??C(k4j zA`?53;D4lcM3&%!hVP{RPjr59ipREE9+I}bNqt*WK0TywSiheti>@=j%_+x-E6Kra zY5v%{?qtU@OSh$o0sR$xX2={gdH0jIzBYSa-Fix+2K6N3e$J~2;=C-PLa-gm?yj+o$DG4-Tq^WObp!5*ey_ECRH<+5C%oxS~c*=(V4kOCg_GH*SgM zWCQn8R0hYg4x)L`!t|)Q4^)9gmW@72L0{lOD<38;UfR{DF5a}pPP_6KoH#b42XS7v zSMWWb@ft**jd+r%0PaBPiXv48R#&__My(kdP|4YrXLB8bToaxX&tj{nlXaEGNL?3g&;)X8G&{?e(A=8_7mveMqx&9h-mhM+F{&a!4*oXg(MXRJ?A zImWltRh+RgppWBM^6-)-rDtkO)qA;rES-qD$$PoaTJ|o<{g|EGl(geHiB(uZuVVsi zmDi3PAKEIRM_xM~>luii-#F@J2Ok-2*gR?HC3 zzyJ&4EHsW7r-%{yvh>;)v!3mYbiUR6k}i&0$XO#IWd~Ym_g&+_ljK^?m^=ZuBiOKw zj@a#)ot5=x+c|4+c5Qi?w>MZtM(>_jfA1Bf9#=<|fvw{(`qmiMt!sMMee0?pvJn*m zVtsbwMU;TV;bCTZy7n0KvoD3exi|7@4Y6GI`9P#+ychDC^9ZWpjsYyg>#AN`7sw5$ zOAxaRwQ5r>M-$ezpte2iyqrCla?zDXv}S9{F){|SVrnIpr(CnCrI-qGd%sig1g$4_ zbLG&w9N9AUm0W{>{>6`ysA~%S znN+r&v~pEC>}Y@fWzQ1vUSE}AykBYC%DB0tjU{&|0}Ketks_;U!(-`hYj@eRgdr%9 zYme>m&`TgK>sI}i3NKe?M)VxhRcm}yLg*RwJ}g?+>ZtpL=L%mI{uA#P{*Zoo$8dNz z;BQ;rzB*71f38uFVNtdks_S$i&%L_U8(XaTYEPj7wYOkC_(&8qL{&?irG?!@?EHf! z)}E4v8CG;}nAW)+W8n{KUgY!MaYBqT*2Z&OSbZ^l$+Ncf&GsSo2gJ3m zb;np;2z~*5Ii2}ik{G^nX@M5Ot>&J0jS;OOCTVoH2bMhO?opN=w>xtPPhE&B$ zUE7bdR|Tu%(W6yA?}^DH=I-wo-ZgUf+3X!C7nSOXAN6is4!c8K#`Ds~Znr*0N(|D}+erP{7UeGgWG|rQ;k@nB4u~Fya z;m`<<6S}(Wn27ArS1*;hW4Coz^IxYIwz2KW=b4lEKJW5?+IJd3}4= zha;u-EL2hZ`sTa>y3SimaHQaTWUOD7x>@sV%9fg&4}@!6UuC~SOdr+Ic0Ol_%NF#; zhNIsZwz9=|?iV8>Sy;|m3K^NIm#s%0-`9h)XAW+it7_3fG;-sF$z3YfDasDk3UI%ig1%*O)S3-Y;Ef5}qp}cH5#^ zI!Z4hi&`s&L0&by)9dU9n`NY zYuy!&dL?pQyvbMKmgDUQv+-RRV>7p7Yt}Q$71J8dGAb?d1h(+FkiviD`v5Sa0o|ZG_TdjT-u!8xg+kius<&!);|0B zc8#8@o8xpiuw7kC&>js>3-{3(Vsu-)j8(Se?Ve~{o;P1diBvi2XOG`f z(nVIFfR@aHYsJ~^=Zdd)bGW@Ftd>&Zf!Mj1uQNZ?T+kg$zSey>zG^P%T8vHo|4yG9 zx<2EAuFANqJAYi!wJG0?&NKfN=TN7-#@#y&eMNQG z?%Qd+|2?5dDYeg`J&VwZ8alfH992-6Bl|B`KFaF}_Rrz5kxM?K4eTNAW+d>Y-o@TW zvB0Ap&EuDe`6EVn9Zbf?E^)zP6I+z`3$X9vs)9DR?OXf$a14(W*B8`MGTg7MKa9n) ztpAs`j_i&|4%x}az2Ah4Jw7p|z!Dg9qoE9O0~qj}Ct362YbWmRKLny>Z$tXf{0 z!qc67O{4u%*Hi=BW%W9vIVKHP1%4(NHWI#^<8Do-)4ye%KR3nV!Y+&-Bq-YRudC0s zG%oN01rV>P?b(Fmd5z3?elrV4Hquy!1ru~y(~*?~<2hmcD;--;xUEg$;cillc3u!3 zpN{-#x|SQ-0oO_z6RKR$ugi(z#<)w5pw^07!y7}rqPe~noEN9OtNE6xacqDdz>2(l zA!ttP9n|QT2zX-ng3sV)Nilym78vQQjzXVnY1Z$Pto)SM^4RVV$JW;J`J?Jr(`c#G ze^>jdBY4djy>u+Fx4T1?c?FiJZ$$3D7db@TzKlMN)d$j(6G=XhijXUKg647uge7t4 zr1-dzTE>}4^SLAeP2LdquocIW9q?G8*~@CPlFlM4=QPe4eV#}>534|(6>8WQmNYYj zf36uWEL=^Jgp{02^5Q$NSBsd=j+`7nkoA^V?&3|syxdV^zV(ghiaD*JOZeRW$fvaW-Sy@0 zaqY@vAJpA8RK;r;`XjXx%K7ohQ9;xq0&h!0_k0~&L`65##j%Zb-0=%BAiSW;;T3=` zx8lwl-uFjcq3lD%9yADli5Abwj{9LFd`r?J90-oCDwhh)^ded`&zt7^;) zO>(3$&p1#ST6r}zD4ef^%GAxVS*FMP=)#de_NQSf-bWY2bAR0E!j^zM!q-GZMWN67 z*)LHOc9b1?2bvjqW|sRu6K1D`U&OIFUc07vmuQhlmN@Txio)v1@Tfd2k?Vzpqm>`} zRPhkr3E#tcJTY%MOf7D9aWH#cfD4h=XI1dmT9$XT^Y}h1*7B7wJElxFD2r0 zJWSMUKYcjG2OM8h1i*3QbS>c_h_wdFJIA}-If6RS!V&y&jdM}4_GkKpDyE(z@%|Z? zbdOtRK9Sa3`ChK(oh%2A1t-e*VbVmj?U;Te zWg(^vR0*5#vF0de?aKp*u==s?YYhcr^uN&9KzVLgGTRXm`9KM2od=#uF(8>WBN91S zfAF1DZ_ys=uGtUdeJ!qdQe&iEhZoE>jM;VId1uJg6Dsts9aBdw?_uGZ^4q;v|2^uu*Nq1`*fzo)KKxQLarxQ%60s?{^({##@tQ|9(1KTZ2oA#C@B7r~5t= zxn6DlK{ch-=6Cuutli#a6(#QVK}COE@3Fftm;H!GqE2tzh%=xB>i|SZtf*1HJIXWLkEFV+y;i&|?LPkB{mhyvkn zn3MXCcNg^ENdsE6cR+R{aJ*7`PtIQA)za#}6h+Irnb(t8%`7vq_DV%L0&7>L_5)q6 z9!8`K598XzzWdq+XIV)z#zdghd%JQNvR86F!=2ZC@Y&b{XA+jSaY;30kww-KiTYXh ztub;W0ENm-D6)V)*%_18TFUl5lQWvA8t)h0OuhC>CgZaPnr%l(_5NLgIkpPyu*bD_ zb)_1u>c2-zR{~0l64LOtEs^!uu-Fd7x~_Nkku6!q#yl6gQtvI}UX8YLL~rH2&+Fa1 z!#Zbs-M4OvJo$b*hU_m>>`7ii+(32buTyLg6%^u(ZY|GM*o_pkURFFoJ!WlMe>|-* zB6{erD&`uB>qKMqChn*CiAJZ!xS=SI`|DFN1lE5N-4=EJU9JZ~&$9mf>nSeK^pf6G zzFaGdC^;y9vB2;nQTMp8rc&K*_mz&UPAg(WvaWU!p~QO~6han_0XvP;%l!Mc(8x?p4agv1#ovq=o8Tca0%xaj{ll`51yP z`2V43%8G+CAS5N@)UAVaJ|btJjk!1;(1k3c4~}%R6qdORd4cPYWH89}nSyKGjAcA4 zf_s;fd@O0Cw%)CzEF`L)t*qT%r@5-RoINg! zJ10eni<-5a<2ZYw78;l%N6^g>#_@m$$uLx`5LpI1GHW4{Y8_)0CaV7Q&#NJ;1+06e z-=yi!@mNPdHtMW0DAJuJ^2RJDZ!WK#G#`pLUiCoAqI#aK*-u?73p)Hl^g$lr)w{PA z7f`-?^|BJOT;GX$2v!9v)3rl+1#Z9VaplaDCRQl1ZOr;MSLBFJawNgNiPyVNAFEbG zhSUdg^hTYZdmSw*VqrFNLh8`IixZLNtmhi#yI#kWs(9+v)+hPdQg8RUU(BLnF^+<2-D$aTZyOVCGHu))BjM3lsc#hZ z9(@1xS|Z}E>*ci?zK=T@a+$|vD)V%?jD^Q`Tb|X1WWLaMd-vT$N7=XdSm#1giPz&P zLw!Bsx@*QAT2TS(yhg+m5)LXQxg)E0=FN*OG(+bn;yV={?!j-{vZY^{-eg5cW0xnf z_Yn&JT<8cbs9RXhcuoNJl3hIf#t!DE)J>*4XnEop8Z|%VyVPZld>wzx&uSxl;d%{f zQ)t%@NlSp_Aj>QG#&x7%J1k|HR`Y4`L{@U}9~#BSCU?plEN z6pl5Ap;)z)S!&Nv^oL~ipf9m~j;P=Op2e#eeHH)?sLmz+5L*z1bwZ!bs>qb;BL`&`xj7{BJOl6AV!y{_4r(&eMZg7yTW;aG;Z&fnCaZM+CbHy>rx&p`+}hJr;9&s?YZ--9+ad`;5~r zqRzG@KFHEo+Cy?}?!w~dr{i;ZO1iH$cUHu)t?A0N_er_WgCZtHk%+3ypP;KNA5?I1jOmKb|5WGRm0E~b&aqYzvv{=Q{T24o(E{)Zx z+B|_X|Mk%%!Q|a1k&AsIO!1)o*CBxkHr;#IZ_AHnJw#eQNilccmB)FW@uwYt#om!4 z>JR1~%k?DeXU6g%>u0x42CmueVde3(Xpl8B$0AhL;5n3J_tU8bC^+U}+dkzWQ?47Y zlr^B7+qN?`=xbeSXT7G}tf&y0aff)GJ$Xx?_#{?EIlhss9(=(bu8S+!0(6(X?JKGk z)9P<^^hkP5RNenpSD=5R&u^Nu;^UIu>=$UyfW{FwOk}ec^%?)S)3YtxSA%a<7W%4m z^pT$9i9U8$431343YY>y+vDNS|7?Eh7mx)!(D0(@3LWBJGgm}4Dk;&X{Dwo6cc%G)JtA zOeAZTB{YF`6SoY1k=JDGhs#<1@Nu38XaXY76Eid4hVGwmbvkw)aYbt-c=|Uly*tt; z?m__!UOlPTFy2)B0LFdZy<8)im7^Yn7$P`p83@j9h{CR}hxBI|HRYi_`b7NluEq-B zh8~yj0W%mJPtwDFTJOuV1|OQ9Lwf0rMZgMJYyA{t_eS&Lev|V>MeVUOBK>{57UQi?FgB^?D}#R+_clwOX%ig4a;nQ?0gTyW<** zdUfVkp8s(2Y3zyi?#Vk-*ob(K6mW8P2Cv_ONqx?vF$X!~1Q|+f;eenBwE(>4C8ap@g%f$~>6E?=fxg*kEkR&ZdJg?x#XfW3S)F1l{}R zIr*@(Z$4oC@$cJnO4OHX&(#fA^(L|)pUX1jeGr!MrQ&$Wv)MGYrY^q$oUTt{Kp&13 z@O(f0-PWFZ|9A=Y{v@sYjACmOdvVWbFC{yJ*7PDr;%b7@dX}@dX~rm7O8A9j*Rjp) ze?(SC_5NNxJx13aGE>aP*&J^X7dZ+e^2+`FJ7Tu^_Oryiwz$NvOS|$ImN~F2wW*B# z-V6lBG4wgddbS5k@*wc)fiRC}ax!n;?NVZJVg?RG=;Tsff8w*mVM(KsWu4ULviwiY z1*q`3BJ#3cTK8X;&rlXEXfx#wYc6`QH{Uxk;OJV~^+OGX9jZh`tX;EedrTbnQL2d8 z2_gj`9&0rI(?5^wSkqS=ll`x1-xR$q|K>nQ;r|0? C6b7sS literal 0 HcmV?d00001