Files
confidence-engine/tests/graph/unknown-answerability.test.js
T

139 lines
5.1 KiB
JavaScript

import { describe, expect, it } from "vitest";
import {
assessUnknownAnswerability,
assessUnknownAtomicity,
} from "@/lib/graph/question-formulator.js";
import { applyValidatedProposal } from "@/lib/graph/apply-proposal.js";
import { makeGraph, makeNode } from "@/lib/graph/schema.js";
const COMMERCIAL_SCENARIO =
"I have developed a new reasoning method that aims to help people determine whether they have enough justified confidence to make a decision. I believe it could become a commercial product, but I do not yet know whether it solves a genuine problem, whether people would value it enough to pay for it, or whether it is fundamentally different from existing AI tools. Before investing significant time and money into building it further, I want to determine whether continuing development is commercially justified.";
function makeMeaningfulNoOpProposal() {
return {
addedNodes: [
makeNode({
id: "n-anchor",
label: "Update anchor",
description:
"Anchor state introduced by the answer because the update must contain a meaningful change.",
kind: "state",
status: "known",
confidence: "low",
}),
],
updatedNodes: [],
addedEdges: [],
removedEdgeIds: [],
resolvedUnknownNodeIds: [],
affectedNodeIds: [],
selectedQuestion: null,
};
}
function makeCommercialContainerGraph() {
const parent = makeNode({
id: "n-commercial-parent",
label:
"Commercial justification for whether continuing development is commercially justified",
description:
"Need to know whether this solves a genuine problem, whether people would value it enough to pay for it, and whether it is commercially justified before continuing development.",
kind: "unknown",
status: "unknown",
confidence: "medium",
});
return makeGraph({
centralStatement: COMMERCIAL_SCENARIO,
nodes: [parent],
edges: [],
activeUnknownNodeId: parent.id,
resolvedNodeIds: [],
currentSummary: "Commercial answerability fixture",
});
}
describe("assessUnknownAnswerability", () => {
it("flags commercial-validation container unknowns as non-answerable", () => {
const graph = makeCommercialContainerGraph();
const unknown = graph.nodes[0];
const atomicity = assessUnknownAtomicity({ node: unknown, graph });
const answerability = assessUnknownAnswerability({ node: unknown, graph });
expect(atomicity.atomicity).toBe("composite");
expect(answerability.independentlyAnswerable).toBe(false);
expect(answerability.decompositionRequired).toBe(true);
expect(answerability.prerequisiteConceptCount).toBeGreaterThan(1);
});
it("keeps one-concept denominator unknowns independently answerable", () => {
const unknown = makeNode({
id: "n-denominator",
label: "Complaint rate denominator",
description:
"Need the denominator because it directly determines the complaint rate.",
kind: "unknown",
status: "unknown",
confidence: "high",
});
const graph = makeGraph({
centralStatement: "Production increased while complaints increased.",
nodes: [unknown],
edges: [],
activeUnknownNodeId: unknown.id,
resolvedNodeIds: [],
currentSummary: "Denominator answerability fixture",
});
const result = assessUnknownAnswerability({ node: unknown, graph });
expect(result.independentlyAnswerable).toBe(true);
expect(result.decompositionRequired).toBe(false);
expect(result.prerequisiteConceptCount).toBeLessThanOrEqual(1);
});
});
describe("answerability-triggered decomposition", () => {
it("decomposes a non-answerable parent into independently answerable child investigations", () => {
const graph = makeCommercialContainerGraph();
const result = applyValidatedProposal({
situationGraph: graph,
proposal: makeMeaningfulNoOpProposal(),
});
expect(result.success).toBe(true);
expect(result.decompositionPerformed).toBe(true);
expect(result.decompositionTriggeredByAnswerability).toBe(true);
expect(result.selectedContainerUnknown).toBe("n-commercial-parent");
expect(result.selectedChildUnknown).toBe(result.selectedUnknownAfter);
expect(result.independentlyAnswerable).toBe(false);
expect(result.prerequisiteConceptCount).toBeGreaterThan(1);
expect(result.selectedUnknownAfter).not.toBe("n-commercial-parent");
expect(result.selectedQuestion.question).toBe(
"Who experiences this problem?",
);
});
it("keeps the parent unresolved while selecting a child unknown", () => {
const graph = makeCommercialContainerGraph();
const result = applyValidatedProposal({
situationGraph: graph,
proposal: makeMeaningfulNoOpProposal(),
});
const parentNode = result.updatedSituationGraph.nodes.find(
(node) => node.id === "n-commercial-parent",
);
const selectedChild = result.updatedSituationGraph.nodes.find(
(node) => node.id === result.selectedUnknownAfter,
);
expect(parentNode.status).toBe("unknown");
expect(selectedChild.parentId).toBe(parentNode.id);
expect(selectedChild.status).toBe("unknown");
});
});