fix(confidence-engine): unwrap focused deconstruction response
This commit is contained in:
@@ -13,18 +13,22 @@ import { describe, it, expect, vi } from "vitest";
|
||||
function makeMockProvider(inventedTargetNodeId) {
|
||||
return {
|
||||
generateReconstruction: vi.fn().mockResolvedValue({
|
||||
targetNodeId: inventedTargetNodeId,
|
||||
observations: ["doc is minimal", "processes in founder's head"],
|
||||
uncertainties: ["whether formal docs can capture tacit knowledge"],
|
||||
assumptions: ["documentation is primary mechanism for knowledge transfer"],
|
||||
relationships: [
|
||||
{ from: "founder", to: "processes", type: "holds", rationale: "tacit" },
|
||||
{ from: "ops-context", to: "docs-infra", type: "depends_on", rationale: "formal docs required" },
|
||||
],
|
||||
possibleFollowUpQuestions: [
|
||||
"What processes does the founder hold tacitly?",
|
||||
"How is knowledge transferred when founder is unavailable?",
|
||||
],
|
||||
response: {
|
||||
targetNodeId: inventedTargetNodeId,
|
||||
observations: ["doc is minimal", "processes in founder's head"],
|
||||
uncertainties: ["whether formal docs can capture tacit knowledge"],
|
||||
assumptions: ["documentation is primary mechanism for knowledge transfer"],
|
||||
relationships: [
|
||||
{ from: "founder", to: "processes", type: "holds", rationale: "tacit" },
|
||||
{ from: "ops-context", to: "docs-infra", type: "depends_on", rationale: "formal docs required" },
|
||||
],
|
||||
possibleFollowUpQuestions: [
|
||||
"What processes does the founder hold tacitly?",
|
||||
"How is knowledge transferred when founder is unavailable?",
|
||||
],
|
||||
},
|
||||
providerApiPath: "/api/chat",
|
||||
providerExecution: { chatRequestAttempted: true },
|
||||
}),
|
||||
};
|
||||
}
|
||||
@@ -85,12 +89,16 @@ describe("focused-deconstruct targetNodeId identity boundary", () => {
|
||||
vi.doMock("@/lib/llm/provider", () => ({
|
||||
getProvider: () => ({
|
||||
generateReconstruction: vi.fn().mockResolvedValue({
|
||||
targetNodeId: "some-invented-id",
|
||||
observations: mockObs,
|
||||
uncertainties: mockUnc,
|
||||
assumptions: mockAssm,
|
||||
relationships: mockRel,
|
||||
possibleFollowUpQuestions: mockFuq,
|
||||
response: {
|
||||
targetNodeId: "some-invented-id",
|
||||
observations: mockObs,
|
||||
uncertainties: mockUnc,
|
||||
assumptions: mockAssm,
|
||||
relationships: mockRel,
|
||||
possibleFollowUpQuestions: mockFuq,
|
||||
},
|
||||
providerApiPath: "/api/chat",
|
||||
providerExecution: { chatRequestAttempted: true },
|
||||
}),
|
||||
}),
|
||||
}));
|
||||
@@ -158,17 +166,21 @@ describe("focused-deconstruct targetNodeId identity boundary", () => {
|
||||
vi.doMock("@/lib/llm/provider", () => ({
|
||||
getProvider: () => ({
|
||||
generateReconstruction: vi.fn().mockResolvedValue({
|
||||
targetNodeId: modelInventedId,
|
||||
observations: ["Documentation is minimal."],
|
||||
uncertainties: [],
|
||||
assumptions: [
|
||||
"That formal documentation is the primary mechanism for capturing or transferring the founder's tacit knowledge of processes.",
|
||||
],
|
||||
relationships: [
|
||||
{ from: "Founder", to: "Processes", type: "holds" },
|
||||
{ from: "Operational Context", to: "Documentation Infrastructure", type: "affects" },
|
||||
],
|
||||
possibleFollowUpQuestions: [],
|
||||
response: {
|
||||
targetNodeId: modelInventedId,
|
||||
observations: ["Documentation is minimal."],
|
||||
uncertainties: [],
|
||||
assumptions: [
|
||||
"That formal documentation is the primary mechanism for capturing or transferring the founder's tacit knowledge of processes.",
|
||||
],
|
||||
relationships: [
|
||||
{ from: "Founder", to: "Processes", type: "holds" },
|
||||
{ from: "Operational Context", to: "Documentation Infrastructure", type: "affects" },
|
||||
],
|
||||
possibleFollowUpQuestions: [],
|
||||
},
|
||||
providerApiPath: "/api/chat",
|
||||
providerExecution: { chatRequestAttempted: true },
|
||||
}),
|
||||
}),
|
||||
}));
|
||||
@@ -217,4 +229,55 @@ describe("focused-deconstruct targetNodeId identity boundary", () => {
|
||||
const stored = { ...json };
|
||||
expect(stored.targetNodeId).toBe(originalNodeId);
|
||||
});
|
||||
|
||||
it("provider envelope fields do not leak into API response", async () => {
|
||||
vi.resetModules();
|
||||
|
||||
vi.doMock("@/lib/llm/provider", () => ({
|
||||
getProvider: () => ({
|
||||
generateReconstruction: vi.fn().mockResolvedValue({
|
||||
response: {
|
||||
targetNodeId: "nk04xvk",
|
||||
observations: ["obs"],
|
||||
uncertainties: ["unc"],
|
||||
assumptions: ["asm"],
|
||||
relationships: [],
|
||||
possibleFollowUpQuestions: ["fuq"],
|
||||
},
|
||||
providerApiPath: "/api/chat",
|
||||
providerExecution: { chatRequestAttempted: true, chatRequestSucceeded: true },
|
||||
}),
|
||||
}),
|
||||
}));
|
||||
|
||||
const { POST } = await import("../app/api/focused-investigation/deconstruct/route.js");
|
||||
|
||||
const response = await POST(
|
||||
new Request("http://localhost/api/focused-investigation/deconstruct", {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({
|
||||
targetNodeId: "nk04xvk",
|
||||
targetLabel: "label",
|
||||
targetDescription: "desc",
|
||||
centralStatement: "central",
|
||||
question: "q?",
|
||||
answer: "a.",
|
||||
}),
|
||||
}),
|
||||
);
|
||||
|
||||
expect(response.status).toBe(200);
|
||||
const json = await response.json();
|
||||
|
||||
// Semantic fields present
|
||||
expect(json.success).toBe(true);
|
||||
expect(json.targetNodeId).toBe("nk04xvk");
|
||||
expect(json.observations).toEqual(["obs"]);
|
||||
expect(json.possibleFollowUpQuestions).toEqual(["fuq"]);
|
||||
|
||||
// Provider envelope fields must NOT appear in the response
|
||||
expect(json.providerApiPath).toBeUndefined();
|
||||
expect(json.providerExecution).toBeUndefined();
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user