reasoning: suppress explanation question without relationship structure

This commit is contained in:
2026-08-10 10:17:35 +01:00
parent 1a31949a48
commit 4c5666dfb3
3 changed files with 184 additions and 1 deletions
@@ -279,4 +279,122 @@ describe("reasoning-pattern validation", () => {
expect(result.selectedQuestion?.nodeId).not.toBe("n-incompatible-child");
expect(result.selectedQuestion?.reasoningPattern).toBe("decision");
});
it("preserves potentially_related with questionRequired=true for meaningful shared structure", () => {
// Two observations sharing "revenue" concept, both with known direction ("up").
// With confirmed comparability (via stored state), condition 2 triggers:
// sharedConcepts.size > 0 && all directions known → potentially_related
const graph = makeGraph({
centralStatement: "Revenue increased. Revenue doubled.",
nodes: [
makeNode({
id: "n-revenue-1",
label: "Revenue increased.",
description: "Revenue increased.",
kind: "observation",
status: "supported",
confidence: "high",
}),
makeNode({
id: "n-revenue-2",
label: "Revenue doubled.",
description: "Revenue doubled.",
kind: "observation",
status: "supported",
confidence: "high",
}),
],
edges: [],
activeUnknownNodeId: null,
resolvedNodeIds: [],
currentSummary: "Potentially related regression fixture",
reasoningState: {
comparabilityStatus: "confirmed",
comparabilityReason: "Stored from earlier assessment.",
comparabilityEvidence: [],
relationshipStatus: "potentially_related",
relationshipReason: "Observations concern the same subject but do not assert a direct contradiction.",
relationshipAssessed: true,
contradictionReasoningAllowed: false,
reasoningStages: [
{ stage: "comparability", status: "confirmed", outcome: "Stored." },
],
},
});
const relationship = classifyObservationRelationship(graph);
expect(relationship.relationshipStatus).toBe("potentially_related");
expect(relationship.questionRequired).toBe(true);
const result = applyValidatedProposal({
situationGraph: graph,
proposal: {
addedNodes: [],
updatedNodes: [
{
nodeId: "n-revenue-2",
previousStatus: "supported",
newStatus: "resolved",
previousValue: null,
newValue: "Revenue doubled confirmed by accounts.",
reason: "Regression test update.",
},
],
addedEdges: [],
removedEdgeIds: [],
resolvedUnknownNodeIds: [],
affectedNodeIds: [],
selectedQuestion: null,
},
});
expect(result.success).toBe(true);
});
it("preserves contradiction with questionRequired=true for genuinely opposing observations", () => {
const graph = makeGraph({
centralStatement:
"The service was reported as available throughout the hour and unavailable throughout the same hour.",
nodes: [
makeNode({
id: "n-available",
label: "The service was available throughout the hour.",
description: "The service was available throughout the hour.",
kind: "observation",
status: "supported",
confidence: "high",
}),
makeNode({
id: "n-unavailable",
label: "The service was unavailable throughout the same hour.",
description: "The service was unavailable throughout the same hour.",
kind: "observation",
status: "supported",
confidence: "high",
}),
],
edges: [],
activeUnknownNodeId: null,
resolvedNodeIds: [],
currentSummary: "Contradiction regression fixture",
reasoningState: {
comparabilityStatus: "confirmed",
comparabilityReason: "Stored from earlier assessment.",
comparabilityEvidence: [],
relationshipStatus: "contradictory",
relationshipReason: "The observations assert mutually incompatible states about the same subject.",
relationshipAssessed: true,
contradictionReasoningAllowed: true,
reasoningStages: [
{ stage: "comparability", status: "confirmed", outcome: "Stored." },
],
},
});
const relationship = classifyObservationRelationship(graph);
expect(relationship.relationshipStatus).toBe("contradictory");
expect(relationship.questionRequired).toBe(true);
});
});