feat(confidence-engine): expose initial reconstruction evidence

This commit is contained in:
2026-09-05 12:39:17 +01:00
parent 7472b6ecb0
commit fb49df87aa
4 changed files with 40 additions and 2 deletions
+7
View File
@@ -19,6 +19,13 @@
- Targeted deterministic suite passed; live v0.5 semantic/reliability validation remains pending.
- 502 structured-output reliability remains a separate unresolved issue.
## Initial reconstruction observability
- Successful `/api/cases/start` responses now expose the validated initial `reconstruction`, the exact object used by `buildInitialGraph()`.
- Semantic experiments can compare `reconstruction.relationships` directly with projected `e-rel-*` SituationGraph edges; this is observability only and does not change reasoning semantics.
- Owning deterministic tests pass. Ten broader orchestrator failures were observed and classified as unrelated to this increment, but were not proven pre-existing because non-mutating baseline execution was blocked by the existing Vitest apparatus.
- No live validation has been rerun against this observability boundary. Next restart point: exactly one production-default `/api/cases/start` call using the fixed manufacturing scenario, comparing reconstruction relationship E directly with its projected graph edge.
## Current product architecture
Three distinct routes, not a single page:
+1
View File
@@ -496,6 +496,7 @@ export async function startCase(body, dependencies = {}) {
return {
success: true,
summary: analysis.reconstruction?.summary ?? null,
reconstruction: analysis.reconstruction,
situationGraph,
selectedQuestion,
diagnostics: buildDiagnostics({
+29 -1
View File
@@ -33,9 +33,33 @@ describe("app/api/cases/start route", () => {
});
it("returns 200 on success", async () => {
const reconstruction = {
summary: "Validated reconstruction summary",
relationships: [
{
id: "r1",
fromId: "u-intervention",
toId: "u-problem",
relationship: "depends_on",
description: "The intervention depends on the unresolved problem.",
confidence: "high",
},
],
};
mockStartCase.mockResolvedValue({
success: true,
situationGraph: { nodes: [{ id: "n1" }], edges: [] },
reconstruction,
situationGraph: {
nodes: [{ id: "n1" }],
edges: [
{
id: "e-unrelated",
fromNodeId: "n1",
toNodeId: "n1",
relationship: "supports",
},
],
},
selectedQuestion: null,
diagnostics: {},
});
@@ -50,6 +74,10 @@ describe("app/api/cases/start route", () => {
);
expect(response.status).toBe(200);
await expect(response.json()).resolves.toMatchObject({
success: true,
reconstruction,
});
});
it("returns 400 for invalid request input", async () => {
+3 -1
View File
@@ -371,12 +371,14 @@ describe("lib/graph/orchestrator startCase", () => {
});
it("builds a valid graph on successful analysis", async () => {
mockAnalyseScenario.mockResolvedValue(makeAnalysisResult());
const analysis = makeAnalysisResult();
mockAnalyseScenario.mockResolvedValue(analysis);
const { startCase } = await import("@/lib/graph/orchestrator.js");
const result = await startCase({ scenario: "Scenario text" });
expect(result.success).toBe(true);
expect(result.reconstruction).toBe(analysis.reconstruction);
expect(result.situationGraph.centralStatement).toBe("Scenario text");
expect(result.situationGraph.currentSummary).toContain("Nodes:");
expect(result.diagnostics).toMatchObject({