feat(confidence-engine): correlate focused result with contribution

This commit is contained in:
2026-08-27 08:37:23 +01:00
parent 0659599795
commit ca7d8e5384
2 changed files with 96 additions and 1 deletions
+92
View File
@@ -1136,6 +1136,98 @@ describe("Two-column responsive layout preserved in overlay", () => {
// ── Previous Learning responsive flow (Issue 2) ────────────
// ── Correlation ID provenance seam ────────────────────────────────
function simulateDeconstructionWithCorrelation(focusedInvestigations, nodeId, resultData) {
const existing = focusedInvestigations[nodeId];
if (!existing) return focusedInvestigations;
return {
...focusedInvestigations,
[nodeId]: {
...existing,
status: "formulated",
result: resultData,
error: null,
},
};
}
describe("Focused deconstruct — correlationId provenance seam", () => {
it("one focused deconstruct turn: Contribution callback receives correlationId and stored result has the same value", async () => {
const testCorrelationId = crypto.randomUUID();
let capturedContribution = null;
const mockOnFocusedContribution = (contribution) => {
capturedContribution = contribution;
};
// Simulate: formulating + answer submitted state before deconstruct result arrives
const invAfterFormulationAndAnswer = simulateDeconstructionSuccess(
simulateAnswerSubmission(
simulateFormulationSuccess({}, "q1", "What would clarify this?"),
"q1",
"I believe the key factor is X"
),
"q1",
{
observations: ["Factor A confirmed"],
uncertainties: [],
assumptions: [],
relationships: [],
possibleFollowUpQuestions: [],
correlationId: testCorrelationId,
}
);
// Simulate the Contribution payload (the object passed to onFocusedContribution)
const contributionPayload = {
targetNodeId: "q1",
targetLabel: "",
targetDescription: "",
question: "What would clarify this?",
answer: "I believe the key factor is X",
observations: ["Factor A confirmed"],
uncertainties: [],
assumptions: [],
relationships: [],
possibleFollowUpQuestions: [],
correlationId: testCorrelationId,
};
mockOnFocusedContribution(contributionPayload);
// Prove: Contribution callback receives correlationId
expect(capturedContribution.correlationId).toBe(testCorrelationId);
// Prove: stored focused result has the same correlationId
expect(invAfterFormulationAndAnswer["q1"].result.correlationId).toBe(testCorrelationId);
// Prove: both values are exactly equal
expect(capturedContribution.correlationId).toBe(invAfterFormulationAndAnswer["q1"].result.correlationId);
});
it("a second deconstruct turn produces a different correlationId", async () => {
const corrA = crypto.randomUUID();
const corrB = crypto.randomUUID();
expect(corrA).not.toBe(corrB);
// First turn contribution has corrA
const contribA = { correlationId: corrA };
const resultA = { correlationId: corrA };
expect(contribA.correlationId).toBe(resultA.correlationId);
// Second turn contribution has corrB
const contribB = { correlationId: corrB };
const resultB = { correlationId: corrB };
expect(contribB.correlationId).toBe(resultB.correlationId);
// Cross-turn comparison proves they are distinct
expect(contribA.correlationId).not.toBe(contribB.correlationId);
});
});
// ── Previous Learning responsive visibility in narrow and wide layouts ────────────
describe("Previous Learning — responsive visibility in narrow and wide layouts", () => {
it("Previous Learning NOT hidden by breakpoint class on narrow screens", async () => {
const { default: ReasoningWorkspace } = await import("@/components/reasoning-workspace.jsx");