reasoning: admit verified user-supported unknowns without provenance edges

This commit is contained in:
2026-08-10 19:27:54 +01:00
parent 1fe3cec4bd
commit 9e869cbcb8
2 changed files with 429 additions and 3 deletions
+404
View File
@@ -2537,4 +2537,408 @@ describe("applyValidatedProposal", () => {
);
expect(result.selectedQuestion?.reasoningPattern).toBe("decision");
});
// ── Case 1 — direct user-supported uncertainty, no structural anchor ──
it("Case 1: admitted unknown passes via node-level user support without structural linkage", () => {
const graph = makeCommercialUpdateFixture();
const parentId = graph.activeUnknownNodeId;
const result = applyValidatedProposal({
situationGraph: graph,
answer: "I need evidence that projected office savings are realistic.",
previousQuestion:
"What problem would this need to solve to justify continuing development?",
proposal: {
addedNodes: [
makeNode({
id: "n-savings-realism",
label: "Whether projected office savings are realistic",
description:
"Need to verify whether the projected office savings are realistic, because that determines commercial justification.",
kind: "unknown",
status: "unknown",
confidence: "high",
}),
],
updatedNodes: [
{
nodeId: parentId,
previousStatus: "unknown",
newStatus: "resolved",
previousValue: null,
newValue: "The user needs evidence for projected office savings realism.",
reason: "The answer directs focus to savings realism evidence.",
},
],
addedEdges: [],
removedEdgeIds: [],
resolvedUnknownNodeIds: [parentId],
affectedNodeIds: [],
selectedQuestion: {
nodeId: "n-savings-realism",
question: "What evidence supports the projected office savings?",
reason: "Consequential unknown verified by user-supported meaning.",
},
answerMeaning: {
userSupportedMeaning:
"I need evidence that projected office savings are realistic.",
possibleInference: null,
supportCategory: "uncertain",
resolutionGuidance: "may_resolve",
},
},
});
expect(result.success).toBe(true);
});
// ── Case 2 — two direct user-supported unknowns ──
it("Case 2: two independently supported unknowns both pass via node-level user support (parent stays unresolved)", () => {
const graph = makeCommercialUpdateFixture();
const parentId = graph.activeUnknownNodeId;
// The parent remains unresolved — the answer adds two new unknowns
// without resolving the original question. Both children are independently verified.
const result = applyValidatedProposal({
situationGraph: graph,
answer: "I need evidence the savings are realistic and evidence the move will not materially increase loss of key engineers.",
previousQuestion:
"What problem would this need to solve to justify continuing development?",
proposal: {
addedNodes: [
makeNode({
id: "n-savings-realism-2",
label: "Whether projected savings are realistic",
description:
"Need to verify whether the savings figures are realistic, because that is needed for commercial evaluation.",
kind: "unknown",
status: "unknown",
confidence: "high",
}),
makeNode({
id: "n-retention-impact",
label: "Whether the move materially increases loss of key engineers",
description:
"Need to check whether the relocation increases risk of losing key engineers, because that matters for continuity.",
kind: "unknown",
status: "unknown",
confidence: "high",
}),
],
updatedNodes: [],
addedEdges: [
makeEdge({
id: "e-parent-to-savings",
fromNodeId: parentId,
toNodeId: "n-savings-realism-2",
relationship: "depends_on",
confidence: "medium",
description: "Parent depends on savings verification.",
}),
],
removedEdgeIds: [],
resolvedUnknownNodeIds: [],
affectedNodeIds: [],
selectedQuestion: {
nodeId: "n-savings-realism-2",
question: "What evidence supports the projected office savings?",
reason: "First of two independently verified consequential unknowns.",
},
answerMeaning: {
userSupportedMeaning:
"I need evidence the savings are realistic and evidence the move will not materially increase loss of key engineers.",
possibleInference: null,
supportCategory: "uncertain",
resolutionGuidance: "may_resolve",
},
},
});
expect(result.success).toBe(true);
});
// ── Case 3 — unsupported hallucinated unknown ──
it("Case 3: unsupported hallucinated unknown is rejected without structural linkage", () => {
const graph = makeCommercialUpdateFixture();
const parentId = graph.activeUnknownNodeId;
const result = applyValidatedProposal({
situationGraph: graph,
answer: "We are looking at this mainly for cost reduction — roughly £2M annual savings on office overhead.",
previousQuestion:
"What problem would this need to solve to justify continuing development?",
proposal: {
addedNodes: [
makeNode({
id: "n-office-paint-colour",
label: "Whether office paint colour affects morale",
description:
"Need to know whether paint colour in the current office affects team morale, because that is a potential factor.",
kind: "unknown",
status: "unknown",
confidence: "low",
}),
],
updatedNodes: [
{
nodeId: parentId,
previousStatus: "unknown",
newStatus: "resolved",
previousValue: null,
newValue: "Cost reduction is the primary driver.",
reason: "The answer identifies cost reduction as the main concern.",
},
],
addedEdges: [],
removedEdgeIds: [],
resolvedUnknownNodeIds: [parentId],
affectedNodeIds: [],
selectedQuestion: {
nodeId: "n-office-paint-colour",
question: "What evidence supports the office paint colour hypothesis?",
reason: "Unrelated unknown — should be rejected.",
},
answerMeaning: {
userSupportedMeaning:
"The main reason for considering this is cost reduction, specifically about £2M in annual office-overhead savings.",
possibleInference: null,
supportCategory: "other",
resolutionGuidance: null,
},
},
});
expect(result.success).toBe(false);
expect(result.stage).toBe("proposal_compatibility");
expect(result.errors.join(" ")).toContain(
"explicitly related to an answer-derived node",
);
});
// ── Case 4 — possibleInference only ──
it("Case 4: unknown based on possibleInference only is not admitted through user-support path", () => {
const graph = makeCommercialUpdateFixture();
// AnswerMeaning's userSupportedMeaning shares NO tokens with the unknown.
// possibleInference does mention "workforce" but that must NOT establish support.
const result = applyValidatedProposal({
situationGraph: graph,
answer: "The project timeline is critical.",
previousQuestion: "What problem would this need to solve?",
proposal: {
addedNodes: [
makeNode({
id: "n-workforce-stability",
label: "Whether workforce stability affects the decision",
description: "Need to check whether workforce stability matters, because that could impact scheduling.",
kind: "unknown",
status: "unknown",
confidence: "medium",
}),
],
updatedNodes: [],
addedEdges: [],
removedEdgeIds: [],
resolvedUnknownNodeIds: [],
affectedNodeIds: [],
selectedQuestion: {
nodeId: "n-workforce-stability",
question: "How important is workforce stability to this decision?",
reason: "Inferred consequential unknown — should be rejected.",
},
answerMeaning: {
userSupportedMeaning: "The project timeline is critical to the decision.",
possibleInference: "Workforce stability may matter for scheduling and continuity.",
supportCategory: null,
resolutionGuidance: null,
},
},
});
expect(result.success).toBe(false);
expect(result.stage).toBe("proposal_compatibility");
expect(result.errors.join(" ")).toContain(
"explicitly related to an answer-derived node",
);
});
// ── Case 5 — genuine structural edge ──
it("Case 5: supported unknown with genuine structural edge passes without additional provenance edge", () => {
const graph = makeCommercialUpdateFixture();
const parentId = graph.activeUnknownNodeId;
const result = applyValidatedProposal({
situationGraph: graph,
answer: "We need evidence that projected office savings are realistic.",
previousQuestion:
"What problem would this need to solve to justify continuing development?",
proposal: {
addedNodes: [
makeNode({
id: "n-savings-realism-5",
label: "Whether projected office savings are realistic",
description:
"Need to verify whether the savings figures are realistic, because that is needed for commercial evaluation.",
kind: "unknown",
status: "unknown",
confidence: "high",
parentId,
}),
],
updatedNodes: [
{
nodeId: parentId,
previousStatus: "unknown",
newStatus: "resolved",
previousValue: null,
newValue: "Savings realism evidence is needed.",
reason: "The answer directs to savings verification.",
},
],
addedEdges: [
makeEdge({
id: "e-parent-savings-realism-5",
fromNodeId: parentId,
toNodeId: "n-savings-realism-5",
relationship: "depends_on",
confidence: "medium",
description: "Savings realism is a dependency of commercial justification.",
}),
],
removedEdgeIds: [],
resolvedUnknownNodeIds: [parentId],
affectedNodeIds: [],
selectedQuestion: {
nodeId: "n-savings-realism-5",
question: "What evidence supports the projected office savings?",
reason: "Both supported and structurally linked.",
},
answerMeaning: {
userSupportedMeaning:
"We need evidence that projected office savings are realistic.",
possibleInference: null,
supportCategory: "uncertain",
resolutionGuidance: "may_resolve",
},
},
});
expect(result.success).toBe(true);
});
// ── Case 6 — answerMeaning absent + valid structural linkage ──
it("Case 6: no answerMeaning but valid structural linkage passes (existing behaviour unchanged)", () => {
const graph = makeCommercialUpdateFixture();
const parentId = graph.activeUnknownNodeId;
const result = applyValidatedProposal({
situationGraph: graph,
answer: "We need evidence that projected office savings are realistic.",
previousQuestion:
"What problem would this need to solve to justify continuing development?",
proposal: {
addedNodes: [
makeNode({
id: "n-savings-realism-6",
label: "Whether projected office savings are realistic",
description:
"Need to verify whether the savings figures are realistic, because that is needed for commercial evaluation.",
kind: "unknown",
status: "unknown",
confidence: "high",
parentId,
}),
],
updatedNodes: [
{
nodeId: parentId,
previousStatus: "unknown",
newStatus: "resolved",
previousValue: null,
newValue: "Savings realism evidence is needed.",
reason: "The answer directs to savings verification.",
},
],
addedEdges: [
makeEdge({
id: "e-parent-savings-realism-6",
fromNodeId: parentId,
toNodeId: "n-savings-realism-6",
relationship: "depends_on",
confidence: "medium",
description: "Savings realism is a dependency.",
}),
],
removedEdgeIds: [],
resolvedUnknownNodeIds: [parentId],
affectedNodeIds: [],
selectedQuestion: {
nodeId: "n-savings-realism-6",
question: "What evidence supports the projected office savings?",
reason: "Structurally linked without answerMeaning.",
},
answerMeaning: null,
},
});
expect(result.success).toBe(true);
});
// ── Case 7 — no support and no linkage ──
it("Case 7: unknown with neither user support nor structural linkage is rejected", () => {
const graph = makeCommercialUpdateFixture();
const parentId = graph.activeUnknownNodeId;
const result = applyValidatedProposal({
situationGraph: graph,
answer: "We need evidence that projected office savings are realistic.",
previousQuestion:
"What problem would this need to solve to justify continuing development?",
proposal: {
addedNodes: [
makeNode({
id: "n-hallucinated-unknown",
label: "Whether the kitchen lighting affects productivity",
description:
"Need to know whether lighting matters, because it could impact outcomes.",
kind: "unknown",
status: "unknown",
confidence: "low",
}),
],
updatedNodes: [
{
nodeId: parentId,
previousStatus: "unknown",
newStatus: "resolved",
previousValue: null,
newValue: "Savings realism is the focus.",
reason: "Answer directs to savings verification.",
},
],
addedEdges: [],
removedEdgeIds: [],
resolvedUnknownNodeIds: [parentId],
affectedNodeIds: [],
selectedQuestion: {
nodeId: "n-hallucinated-unknown",
question: "Does kitchen lighting affect productivity?",
reason: "No support, no linkage — should be rejected.",
},
answerMeaning: {
userSupportedMeaning:
"We need evidence that projected office savings are realistic.",
possibleInference: null,
supportCategory: "uncertain",
resolutionGuidance: "may_resolve",
},
},
});
expect(result.success).toBe(false);
expect(result.stage).toBe("proposal_compatibility");
expect(result.errors.join(" ")).toContain(
"explicitly related to an answer-derived node",
);
});
});