fix(reasoning): preserve investigation ownership across selection and question rejection

This commit is contained in:
2026-08-17 17:58:45 +01:00
parent d908f3746d
commit 772ae495c6
7 changed files with 850 additions and 4429 deletions
+42
View File
@@ -1,7 +1,9 @@
import { beforeEach, describe, expect, it, vi } from "vitest";
import { applyValidatedProposal } from "@/lib/graph/apply-proposal.js";
import { determineGraphBackedQuestion } from "@/lib/graph/apply-proposal.js";
import { validateGraphReferences } from "@/lib/graph/utils.js";
import { makeGraph, makeNode } from "@/lib/graph/schema.js";
import liveProductLaunchStartResponse from "@/tests/fixtures/live-product-launch-start-response.json";
const mockAnalyseScenario = vi.fn();
const MOCK_CONFIG = { OLLAMA_MODEL: "configured" };
@@ -588,6 +590,46 @@ describe("lib/graph/orchestrator startCase", () => {
);
});
it("retains ownership when the strongest target's formulated question is rejected", () => {
const situationGraph = structuredClone(
liveProductLaunchStartResponse.situationGraph,
);
const result = determineGraphBackedQuestion({ situationGraph });
expect(result.success).toBe(true);
expect(result.deterministicSelection?.nodeId ?? null).toBe("ntpt9ki");
expect(result.updatedSituationGraph.activeUnknownNodeId).toBe("ntpt9ki");
expect(result.selectedQuestion).toBeNull();
expect(result.noQuestionReason).toBe(
"The selected investigation target remains active, but its current graph-backed question formulation was rejected as too complex.",
);
expect(result.selectedChildUnknown).toBe("ntpt9ki");
expect(result.selectedUnknownAfter).toBe("ntpt9ki");
expect(result.selectedQuestion?.nodeId ?? null).toBe(null);
});
it("replays the captured live product-launch start graph through deterministic graph-backed question selection", () => {
const situationGraph = liveProductLaunchStartResponse.situationGraph;
const result = determineGraphBackedQuestion({ situationGraph });
expect(result.success).toBe(true);
expect(result.updatedSituationGraph.activeUnknownNodeId).toBe("ntpt9ki");
expect(result.deterministicSelection?.nodeId ?? null).toBe("ntpt9ki");
expect(result.answerabilityAssessment?.independentlyAnswerable).toBe(false);
expect(result.answerabilityAssessment?.decompositionRequired).toBe(true);
expect(result.decompositionAttempted).toBe(true);
expect(result.decompositionPerformed).toBe(false);
expect(result.selectedChildUnknown).toBe("ntpt9ki");
expect(result.selectedUnknownAfter).toBe("ntpt9ki");
expect(result.selectedQuestion).toBeNull();
expect(result.noQuestionReason).toBe(
"The selected investigation target remains active, but its current graph-backed question formulation was rejected as too complex.",
);
expect(result.deterministicSelection?.nodeId).not.toBe("nxmeiab");
});
it("includes compatibility diagnostics when provided by analysis", async () => {
mockAnalyseScenario.mockResolvedValue(
makeAnalysisResult({