feat: explain deterministic unknown selection

This commit is contained in:
2026-08-02 15:27:00 +01:00
parent 5ef9710293
commit 586802950d
3 changed files with 321 additions and 25 deletions
+66
View File
@@ -178,6 +178,9 @@ describe("lib/graph/orchestrator startCase", () => {
expect(result.success).toBe(true);
expect(result.situationGraph.activeUnknownNodeId).toBeTruthy();
expect(result.diagnostics.unknownSelectionExplanation?.selectedNodeId).toBe(
result.situationGraph.activeUnknownNodeId,
);
});
it("returns structured failure when graph reference validation fails", async () => {
@@ -262,6 +265,69 @@ describe("lib/graph/orchestrator startCase", () => {
expect(result.diagnostics.compatibilityChanges).toHaveLength(1);
});
it("preserves selected question bytes while adding selection explanation diagnostics", async () => {
const { updateCase } = await import("@/lib/graph/orchestrator.js");
const provider = {
generateReconstruction: vi.fn().mockResolvedValue(
makeProposal({
addedNodes: [
makeNode({
id: "n-build-decision",
label: "Build Confidence Engine decision",
description: "Decision introduced by the answer.",
kind: "state",
status: "supported",
confidence: "medium",
}),
makeNode({
id: "n-commercial-value",
label: "Commercial value definition",
description:
"Need a concrete definition because the decision depends on it.",
kind: "unknown",
status: "unknown",
confidence: "high",
}),
],
addedEdges: [
{
id: "e-build-commercial-value",
fromNodeId: "n-build-decision",
toNodeId: "n-commercial-value",
relationship: "depends_on",
confidence: "medium",
description:
"The decision depends on commercial value definition.",
},
],
selectedQuestion: {
nodeId: "n-commercial-value",
question:
"How should commercial value be defined for this decision?",
reason: "Consequential unresolved uncertainty remains.",
},
}),
),
};
const first = await updateCase(makeUpdateRequest(), {
provider,
config: MOCK_CONFIG,
applyProposal: true,
});
const second = await updateCase(makeUpdateRequest(), {
provider,
config: MOCK_CONFIG,
applyProposal: true,
});
expect(first.selectedQuestion.question).toBe(
second.selectedQuestion.question,
);
expect(first.selectedQuestion.reason).toBe(second.selectedQuestion.reason);
expect(first.diagnostics.unknownSelectionExplanation).toBeTruthy();
});
it("produces a validated update proposal for a valid request", async () => {
const { updateCase } = await import("@/lib/graph/orchestrator.js");
const provider = {