fix(reasoning): reconcile evidence and preserve deterministic continuation
This commit is contained in:
@@ -912,6 +912,92 @@ describe("applyGraphUpdate", () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe("selectActiveUnknownCandidate deterministic tie resolution", () => {
|
||||
it("returns a stable non-null winner when two eligible candidates tie on top score", () => {
|
||||
const decision = makeNode({
|
||||
id: "n_decision_tie",
|
||||
label: "Which option leaves us better off overall?",
|
||||
description: "Decision context",
|
||||
kind: "unknown",
|
||||
status: "unknown",
|
||||
confidence: "medium",
|
||||
});
|
||||
const launch = makeNode({
|
||||
id: "opt_launch_tie",
|
||||
label: "Launch this year",
|
||||
description: "Launch this year.",
|
||||
kind: "option",
|
||||
status: "known",
|
||||
confidence: "high",
|
||||
});
|
||||
const timeline = makeNode({
|
||||
id: "n_customer_decision_timeline",
|
||||
label: "When will the enterprise customer make its decision?",
|
||||
description:
|
||||
"Unknown when the enterprise customer will make its decision, and the timing could still affect launch planning.",
|
||||
kind: "unknown",
|
||||
status: "unknown",
|
||||
confidence: "medium",
|
||||
});
|
||||
const viability = makeNode({
|
||||
id: "n_launch_viability_without_anchor_customer",
|
||||
label: "Is launch commercially viable without the £700,000?",
|
||||
description:
|
||||
"Unknown whether launching this year is still commercially viable without the £700,000 enterprise-customer revenue.",
|
||||
kind: "unknown",
|
||||
status: "unknown",
|
||||
confidence: "medium",
|
||||
});
|
||||
const competitor = makeNode({
|
||||
id: "n_competitor_move_first_risk",
|
||||
label: "Could competitors move first during a 12-month delay?",
|
||||
description:
|
||||
"Unknown whether competitors could move first if launch is delayed by twelve months.",
|
||||
kind: "unknown",
|
||||
status: "unknown",
|
||||
confidence: "medium",
|
||||
});
|
||||
|
||||
const graph = makeGraph({
|
||||
centralStatement: "Launch decision",
|
||||
nodes: [decision, launch, timeline, viability, competitor],
|
||||
edges: [
|
||||
makeEdge({
|
||||
fromNodeId: launch.id,
|
||||
toNodeId: decision.id,
|
||||
relationship: "contained_in",
|
||||
}),
|
||||
makeEdge({
|
||||
fromNodeId: timeline.id,
|
||||
toNodeId: launch.id,
|
||||
relationship: "depends_on",
|
||||
}),
|
||||
makeEdge({
|
||||
fromNodeId: viability.id,
|
||||
toNodeId: decision.id,
|
||||
relationship: "depends_on",
|
||||
}),
|
||||
makeEdge({
|
||||
fromNodeId: competitor.id,
|
||||
toNodeId: launch.id,
|
||||
relationship: "contained_in",
|
||||
}),
|
||||
],
|
||||
activeUnknownNodeId: null,
|
||||
resolvedNodeIds: [],
|
||||
currentSummary: "Tie case",
|
||||
});
|
||||
|
||||
const first = selectActiveUnknownCandidate(graph, []);
|
||||
const second = selectActiveUnknownCandidate(graph, []);
|
||||
|
||||
expect(first?.status).toBe("selected");
|
||||
expect(first?.nodeId).toBeTruthy();
|
||||
expect(second?.status).toBe("selected");
|
||||
expect(second?.nodeId).toBe(first?.nodeId);
|
||||
});
|
||||
});
|
||||
|
||||
describe("validateGraphUpdate", () => {
|
||||
it("accepts a no-op update with added nodes", () => {
|
||||
const graph = makeTestGraph();
|
||||
|
||||
Reference in New Issue
Block a user