feat(confidence-engine): preserve initial reconstruction relationships
This commit is contained in:
+133
-10
@@ -25,9 +25,9 @@ describe("v0.3 prompt", () => {
|
||||
expect(PROMPT_VERSIONS).toContain("v0.3");
|
||||
});
|
||||
|
||||
it("DEFAULT_PROMPT_VERSION was v0.3 on earlier branches (now v0.4)", () => {
|
||||
// This test documents that the old default was v0.3; the new default is v0.4
|
||||
expect(["v0.3", "v0.4"]).toContain(DEFAULT_PROMPT_VERSION);
|
||||
it("DEFAULT_PROMPT_VERSION was v0.3 on earlier branches (now v0.5)", () => {
|
||||
// This test documents that the old default was v0.3; the new default is v0.5
|
||||
expect(["v0.3", "v0.4", "v0.5"]).toContain(DEFAULT_PROMPT_VERSION);
|
||||
});
|
||||
|
||||
it("v0.2 remains available in PROMPT_VERSIONS", () => {
|
||||
@@ -201,6 +201,45 @@ describe("v0.2 backward compatibility", () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe("v0.5 prompt", () => {
|
||||
it("is the production default", async () => {
|
||||
const result = await buildPrompt("Default prompt scenario");
|
||||
|
||||
expect(DEFAULT_PROMPT_VERSION).toBe("v0.5");
|
||||
expect(PROMPT_VERSIONS).toContain("v0.5");
|
||||
expect(result.version).toBe("v0.5");
|
||||
expect(result.prompt).toContain("Default prompt scenario");
|
||||
});
|
||||
|
||||
it("keeps explicit v0.4 unchanged", async () => {
|
||||
const result = await buildPrompt("Explicit v0.4 scenario", "v0.4");
|
||||
|
||||
expect(result.version).toBe("v0.4");
|
||||
expect(result.prompt).toContain(
|
||||
"with no dedicated schema field MUST be preserved explicitly in summary",
|
||||
);
|
||||
});
|
||||
|
||||
it("loads the v0.5 relationship contract", async () => {
|
||||
const result = await buildPrompt("Explicit v0.5 scenario", "v0.5");
|
||||
|
||||
expect(result.version).toBe("v0.5");
|
||||
expect(result.prompt).toContain("reconstruction.relationships");
|
||||
expect(result.prompt).toContain("fromId");
|
||||
expect(result.prompt).toContain("toId");
|
||||
expect(result.prompt).toContain("MUST reference IDs of semantic units");
|
||||
});
|
||||
|
||||
it("retains the provenance stop boundary and interpretation separation", async () => {
|
||||
const { prompt } = await buildPrompt("Contract retention scenario", "v0.5");
|
||||
|
||||
expect(prompt).toContain("Explicit stop boundary for decomposition");
|
||||
expect(prompt).toContain("Once the supplied meaning");
|
||||
expect(prompt).toContain("Interpretation discipline");
|
||||
expect(prompt).toContain("plausibleInterpretations");
|
||||
});
|
||||
});
|
||||
|
||||
// ──────────────────────────────────────────────
|
||||
// Schema validation tests for v0.3-shaped output
|
||||
// ──────────────────────────────────────────────
|
||||
@@ -344,6 +383,90 @@ describe("v0.3 schema validation", () => {
|
||||
|
||||
const result = reconstructionV2Schema.safeParse(input);
|
||||
expect(result.success).toBe(true);
|
||||
expect(result.data.reconstruction.relationships).toEqual([]);
|
||||
});
|
||||
|
||||
it("parses a valid reconstruction relationship", () => {
|
||||
const input = {
|
||||
inputClassification: {
|
||||
primaryType: "decision_request",
|
||||
classificationReason: "test",
|
||||
confidence: "medium",
|
||||
},
|
||||
reconstruction: {
|
||||
summary: "Decision depends on an unresolved quality question.",
|
||||
actors: [],
|
||||
systemsOrObjects: [],
|
||||
expectedStates: [],
|
||||
observedStates: [],
|
||||
differences: [],
|
||||
knownTransitions: [],
|
||||
unexplainedTransitions: [],
|
||||
contradictions: [],
|
||||
importantUnknowns: [
|
||||
{ id: "u1", description: "Whether a quality problem exists", confidence: "high" },
|
||||
{ id: "u2", description: "Whether inspection is appropriate", confidence: "high" },
|
||||
],
|
||||
plausibleInterpretations: [],
|
||||
relationships: [
|
||||
{
|
||||
id: "r1",
|
||||
fromId: "u2",
|
||||
toId: "u1",
|
||||
relationship: "depends_on",
|
||||
description: "Inspection appropriateness depends on the quality problem.",
|
||||
confidence: "high",
|
||||
},
|
||||
],
|
||||
},
|
||||
evidence: [],
|
||||
nextQuestion: {
|
||||
id: "q1",
|
||||
question: "What evidence establishes the quality problem?",
|
||||
targets: ["u1"],
|
||||
reason: "need evidence",
|
||||
expectedInformationValue: "high",
|
||||
},
|
||||
};
|
||||
|
||||
const result = reconstructionV2Schema.safeParse(input);
|
||||
expect(result.success).toBe(true);
|
||||
expect(result.data.reconstruction.relationships).toEqual(input.reconstruction.relationships);
|
||||
});
|
||||
|
||||
it("rejects invalid reconstruction relationship enums and missing endpoints", () => {
|
||||
const validRelationship = {
|
||||
id: "r1",
|
||||
fromId: "u2",
|
||||
toId: "u1",
|
||||
relationship: "depends_on",
|
||||
description: "u2 depends on u1",
|
||||
confidence: "high",
|
||||
};
|
||||
const base = {
|
||||
inputClassification: { primaryType: "other", classificationReason: "test", confidence: "low" },
|
||||
reconstruction: {
|
||||
summary: "test",
|
||||
actors: [], systemsOrObjects: [], expectedStates: [], observedStates: [], differences: [],
|
||||
knownTransitions: [], unexplainedTransitions: [], contradictions: [], importantUnknowns: [],
|
||||
plausibleInterpretations: [], relationships: [validRelationship],
|
||||
},
|
||||
evidence: [],
|
||||
nextQuestion: { id: "q1", question: "What next?", targets: [], reason: "test", expectedInformationValue: "low" },
|
||||
};
|
||||
|
||||
expect(reconstructionV2Schema.safeParse({
|
||||
...base,
|
||||
reconstruction: { ...base.reconstruction, relationships: [{ ...validRelationship, relationship: "updates" }] },
|
||||
}).success).toBe(false);
|
||||
expect(reconstructionV2Schema.safeParse({
|
||||
...base,
|
||||
reconstruction: { ...base.reconstruction, relationships: [{ ...validRelationship, fromId: undefined }] },
|
||||
}).success).toBe(false);
|
||||
expect(reconstructionV2Schema.safeParse({
|
||||
...base,
|
||||
reconstruction: { ...base.reconstruction, relationships: [{ ...validRelationship, toId: undefined }] },
|
||||
}).success).toBe(false);
|
||||
});
|
||||
|
||||
it("validates evidence distinguishing direct_observation from inferred_relationship", () => {
|
||||
@@ -676,8 +799,8 @@ describe("target scenario fixture validation", () => {
|
||||
|
||||
describe("diagnostics prompt version", () => {
|
||||
it("DEFAULT_PROMPT_VERSION is exported correctly", () => {
|
||||
// The current default is v0.4 (was v0.3)
|
||||
expect(["v0.3", "v0.4"]).toContain(DEFAULT_PROMPT_VERSION);
|
||||
// The current default is v0.5 (was v0.3)
|
||||
expect(["v0.3", "v0.4", "v0.5"]).toContain(DEFAULT_PROMPT_VERSION);
|
||||
});
|
||||
|
||||
it("PROMPT_VERSIONS includes both v0.2 and v0.3", () => {
|
||||
@@ -801,8 +924,8 @@ describe("Finding disposition toggle — state machine", () => {
|
||||
// ──────────────────────────────────────────────
|
||||
|
||||
describe("v0.4 prompt", () => {
|
||||
it("DEFAULT_PROMPT_VERSION is v0.4 on this branch", () => {
|
||||
expect(DEFAULT_PROMPT_VERSION).toBe("v0.4");
|
||||
it("DEFAULT_PROMPT_VERSION is v0.5 on this branch", () => {
|
||||
expect(DEFAULT_PROMPT_VERSION).toBe("v0.5");
|
||||
});
|
||||
|
||||
it("v0.4 is in PROMPT_VERSIONS", () => {
|
||||
@@ -879,12 +1002,12 @@ describe("v0.4 prompt", () => {
|
||||
expect(result.prompt).toMatch(/exactly.*one.*question|Do NOT combine/i);
|
||||
});
|
||||
|
||||
it("default buildPrompt (no version arg) resolves to v0.4", async () => {
|
||||
it("default buildPrompt (no version arg) resolves to v0.5", async () => {
|
||||
const result = await buildPrompt("Default version test");
|
||||
expect(result.version).toBe(DEFAULT_PROMPT_VERSION);
|
||||
expect(DEFAULT_PROMPT_VERSION).toBe("v0.4");
|
||||
expect(DEFAULT_PROMPT_VERSION).toBe("v0.5");
|
||||
// Should not contain v0.3 schema-specific differences array (it does have it)
|
||||
// but the prompt should be from the v0.4 file which has the stop boundary text
|
||||
// but the prompt should be from the v0.5 file which has the stop boundary text
|
||||
expect(result.prompt.toLowerCase()).toMatch(/stop|explicit.*stop/);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user