From 7177c7bb61f715c8e12471afd124a169a3d14907 Mon Sep 17 00:00:00 2001 From: robbond Date: Tue, 1 Sep 2026 11:54:02 +0100 Subject: [PATCH] refactor(confidence-engine): make episode preparation server-owned --- components/scenario-form.jsx | 13 -------- lib/graph/schema.js | 1 + tests/ui/scenario-form-episode-done.test.jsx | 35 ++------------------ 3 files changed, 4 insertions(+), 45 deletions(-) diff --git a/components/scenario-form.jsx b/components/scenario-form.jsx index 148b3fd..776b77f 100644 --- a/components/scenario-form.jsx +++ b/components/scenario-form.jsx @@ -6,7 +6,6 @@ import DiagnosticsView from "@/components/diagnostics-view"; import ReasoningWorkspace, { LoadingOverlay, ContinueLaterBanner } from "@/components/reasoning-workspace"; import { mockFetch, AVAILABLE_SCENARIOS } from "@/lib/mocks/confidence-engine/mock-client"; import { deriveFindingsFromContributions, normalizeFindings } from "@/lib/graph/finding-helpers"; -import { prepareCompletedEpisode } from "@/lib/graph/episode-preparation.js"; import { loadInvestigation, saveInvestigation, clearInvestigation } from "@/lib/storage/investigation-storage"; /* Compile-time env resolution — NEXT_PUBLIC_ vars are injected by Next.js at build */ @@ -249,22 +248,10 @@ export async function executeEpisodeDone({ targetNodeId, focusedContributions, findings, - prepareCompletedEpisode: prepFn = prepareCompletedEpisode, episodeDoneServer, synthesizeFn, setResult: setAppState, }) { - const prepared = prepFn({ - situationGraph: resultSituationGraph, - targetNodeId, - contributions: focusedContributions ?? [], - findings, - }); - - if (!prepared?.turns?.length && !prepared?.eligibleCanonicalFindings?.length) { - return { success: false, stage: "preparation", reason: "no_episodic_content" }; - } - const serverResult = await episodeDoneServer({ situationGraph: resultSituationGraph, targetNodeId, diff --git a/lib/graph/schema.js b/lib/graph/schema.js index 832c7ae..110de8a 100644 --- a/lib/graph/schema.js +++ b/lib/graph/schema.js @@ -234,6 +234,7 @@ export const updateCaseEpisodeRequestSchema = z.object({ situationGraph: situationGraphSchema, targetNodeId: z.string().min(1), contributions: z.any().array().optional(), + findings: z.any().array().optional(), }).passthrough(); // ── Helpers ────────────────────────────────────────── diff --git a/tests/ui/scenario-form-episode-done.test.jsx b/tests/ui/scenario-form-episode-done.test.jsx index 134927c..afdf100 100644 --- a/tests/ui/scenario-form-episode-done.test.jsx +++ b/tests/ui/scenario-form-episode-done.test.jsx @@ -9,17 +9,6 @@ const MOCK_SITUATION_GRAPH = { const DISTINCTIVE_GRAPH = { __distinctive_graph__: true }; -function makePreparedEpisode(overrides = {}) { - return { - situationGraph: MOCK_SITUATION_GRAPH, - targetNodeId: "n-q1", - turns: [{ contributionId: "contrib-0001", sequence: 1, question: "Q?", answer: "A?" }], - eligibleCanonicalFindings: [{ findingId: "f-1", proposition: "P1" }], - excludedFindingProvenance: [], - ...overrides, - }; -} - function makeProposal() { return { addedNodes: [], updatedNodes: [{ nodeId: "n-q1", newStatus: "resolved" }], @@ -44,17 +33,9 @@ describe("episode-done orchestration", () => { }; } - function makePrepMock(returnValue) { - return vi.fn().mockReturnValue(returnValue ?? makePreparedEpisode()); - } - - it("1. Successful path order (prepare → synthesize)", async () => { + it("1. Successful path order (server → synthesize)", async () => { const order = []; const serverMock = makeServerMock(); - const prepFn = makePrepMock().mockImplementation(() => { - order.push("prepare"); - return makePreparedEpisode(); - }); serverMock.fn.mockImplementation(async (payload) => { order.push("server"); return { success: true, updatedSituationGraph: DISTINCTIVE_GRAPH, proposal: makeProposal() }; @@ -65,7 +46,6 @@ describe("episode-done orchestration", () => { targetNodeId: "n-q1", focusedContributions: [{ id: "c-1" }], findings: [], - prepareCompletedEpisode: prepFn, episodeDoneServer: serverMock.fn, synthesizeFn: vi.fn().mockImplementation(async () => { order.push("synthesize"); @@ -74,9 +54,8 @@ describe("episode-done orchestration", () => { setResult: vi.fn(), }); - expect(order[0]).toBe("prepare"); - expect(order[1]).toBe("server"); - expect(order[2]).toBe("synthesize"); + expect(order[0]).toBe("server"); + expect(order[1]).toBe("synthesize"); }); it("2. Client sends prepared episode source state to server", async () => { @@ -89,7 +68,6 @@ describe("episode-done orchestration", () => { targetNodeId: "n-q1", focusedContributions: contributions, findings, - prepareCompletedEpisode: makePrepMock(), episodeDoneServer: serverMock.fn, synthesizeFn: vi.fn().mockReturnValue({ ok: true, data: {} }), setResult: vi.fn(), @@ -110,7 +88,6 @@ describe("episode-done orchestration", () => { targetNodeId: "n-q1", focusedContributions: [], findings: [], - prepareCompletedEpisode: makePrepMock(), episodeDoneServer: serverMock.fn, synthesizeFn: vi.fn().mockReturnValue({ ok: true, data: {} }), setResult: vi.fn(), @@ -136,7 +113,6 @@ describe("episode-done orchestration", () => { targetNodeId: "n-q1", focusedContributions: [], findings: [{ id: "f-1" }], - prepareCompletedEpisode: makePrepMock(), episodeDoneServer: serverMock.fn, synthesizeFn: (graph) => { synthesizedGraph = graph; @@ -157,7 +133,6 @@ describe("episode-done orchestration", () => { targetNodeId: "n-q1", focusedContributions: [], findings: [], - prepareCompletedEpisode: makePrepMock(), episodeDoneServer: serverMock.fn, synthesizeFn: vi.fn(), setResult: vi.fn(), @@ -177,7 +152,6 @@ describe("episode-done orchestration", () => { targetNodeId: "n-q1", focusedContributions: [], findings: [], - prepareCompletedEpisode: makePrepMock(), episodeDoneServer: serverMock.fn, synthesizeFn: vi.fn(), setResult, @@ -195,7 +169,6 @@ describe("episode-done orchestration", () => { targetNodeId: "n-q1", focusedContributions: [], findings: [], - prepareCompletedEpisode: makePrepMock(), episodeDoneServer: serverMock.fn, synthesizeFn: vi.fn().mockReturnValue({ ok: false }), setResult, @@ -216,7 +189,6 @@ describe("episode-done orchestration", () => { targetNodeId: "n-q1", focusedContributions: [], findings: [], - prepareCompletedEpisode: makePrepMock(), episodeDoneServer: serverMock.fn, synthesizeFn: vi.fn().mockReturnValue({ ok: true, data: {} }), setResult: vi.fn(), @@ -234,7 +206,6 @@ describe("episode-done orchestration", () => { targetNodeId: "n-q1", focusedContributions: [], findings: [], - prepareCompletedEpisode: makePrepMock(), episodeDoneServer: serverMock.fn, synthesizeFn: vi.fn().mockReturnValue({ ok: true, data: {} }), setResult: vi.fn(),