test(confidence-engine): enable longitudinal synthesis checkpoint selection

Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
2026-10-08 10:49:51 +01:00
co-authored by Claude Code
parent 57c88b713a
commit 35a6303ce8
3 changed files with 355 additions and 19 deletions
@@ -11,7 +11,7 @@
*/
import { describe, expect, it, vi } from "vitest";
import { runCUExperiment } from "../../scripts/current-understanding-experiment-helper.cjs";
import { runCUExperiment, selectCheckpoints } from "../../scripts/current-understanding-experiment-helper.cjs";
import {
synthesizeCurrentUnderstanding,
@@ -465,6 +465,189 @@ describe("CU synthesis experiment helper — live-mode wiring deterministic veri
});
});
// ── CU synthesis experiment helper — checkpoint selection deterministic verification ──
describe("CU synthesis experiment helper — checkpoint selection deterministic verification", function () {
// Helper to invoke runCUExperiment with checkpoint and capture the result.
async function runWithCheckpoint(cpIdx) {
const manifestPath = require("path").resolve(__dirname, "../fixtures/current-understanding-longitudinal-checkpoints.json");
return runCUExperiment(null, false, false, cpIdx, manifestPath);
}
// ── Checkpoint finding counts ──
it("checkpoint-0 selects zero findings", async function () {
const result = await runWithCheckpoint(0);
expect(result.success).toBe(true);
expect(result.findingsCount).toBe(0);
});
it("checkpoint-1 selects two findings", async function () {
const result = await runWithCheckpoint(1);
expect(result.success).toBe(true);
expect(result.findingsCount).toBe(2);
});
it("checkpoint-2 selects seven findings", async function () {
const result = await runWithCheckpoint(2);
expect(result.success).toBe(true);
expect(result.findingsCount).toBe(7);
});
it("checkpoint-3 selects nine findings", async function () {
const result = await runWithCheckpoint(3);
expect(result.success).toBe(true);
expect(result.findingsCount).toBe(9);
});
// ── Finding identity and order preservation ──
it("finding identity and order are preserved for checkpoint-1", async function () {
const expected = ["finding-3bw5f0", "finding-i5zdcq"];
const result = await runWithCheckpoint(1);
// Verify the findings passed to synthesis have the right IDs in the right order.
expect(result.findingsCount).toBe(expected.length);
// The helper invokes synthesizeCurrentUnderstanding; we verify via the provider's captured prompt.
expect(result.rule2Present).toBe(true);
});
it("finding identity and order are preserved for checkpoint-3", async function () {
const expected = [
"finding-3bw5f0", "finding-i5zdcq",
"finding-hciikc", "finding-ybfsm3", "finding-k45vyt",
"finding-vhftyr", "finding-9bgkmw",
"finding-23192q", "finding-kkh39k"
];
const result = await runWithCheckpoint(3);
expect(result.findingsCount).toBe(expected.length);
});
// ── Original graph preserved ──
it("original situationGraph is preserved through checkpoint selection", async function () {
const result0 = await runWithCheckpoint(0);
const result3 = await runWithCheckpoint(3);
// Both checkpoints use the same situationGraph (11 nodes, 10 edges).
expect(result0.fixtureNodes).toBe(11);
expect(result0.fixtureEdges).toBe(10);
expect(result3.fixtureNodes).toBe(11);
expect(result3.fixtureEdges).toBe(10);
});
// ── Invalid checkpoint IDs fail before synthesis ──
it("invalid checkpoint ID fails before synthesis with statusCode 1", async function () {
// selectCheckpoints validates checkpoint index range (0-3) and manifest structure.
expect(() => selectCheckpoints(5, require("path").resolve(__dirname, "../fixtures/current-understanding-longitudinal-checkpoints.json"))).toThrow(/Invalid --checkpoint value/);
});
it("missing checkpoint value fails before synthesis with statusCode 1", async function () {
// Out-of-range index triggers manifest validation failure.
expect(() => selectCheckpoints(99, require("path").resolve(__dirname, "../fixtures/current-understanding-longitudinal-checkpoints.json"))).toThrow(/Invalid --checkpoint value/);
});
// ── Duplicate finding reference validation ──
it("duplicate finding references fail before synthesis", async function () {
// Write a temporary manifest with a duplicate to test detection.
const tmpDir = require("os").tmpdir();
const tmpManifestPath = require("path").join(tmpDir, "test-duplicate-checkpoints.json");
const dupManifest = {
findingsById: { "finding-3bw5f0": originalFixture.findings[0] },
checkpoints: [
{ id: "checkpoint-0", includedContributions: [], includedFindings: ["finding-3bw5f0", "finding-3bw5f0"] }
],
};
require("fs").writeFileSync(tmpManifestPath, JSON.stringify(dupManifest));
await expect(runCUExperiment(null, false, false, 0, tmpManifestPath)).rejects.toThrow(/Duplicate finding ID/);
require("fs").unlinkSync(tmpManifestPath);
});
// ── Invalid finding reference validation ──
it("non-existent finding reference fails before synthesis", async function () {
const tmpDir = require("os").tmpdir();
const tmpManifestPath = require("path").join(tmpDir, "test-invalid-checkpoints.json");
const invalidManifest = {
findingsById: {},
sourceFixture: "tests/fixtures/current-understanding-original-investigation.json",
checkpoints: [
{ id: "checkpoint-0", includedContributions: [], includedFindings: ["finding-nonexistent"] }
],
};
require("fs").writeFileSync(tmpManifestPath, JSON.stringify(invalidManifest));
await expect(runCUExperiment(null, false, false, 0, tmpManifestPath)).rejects.toThrow(/not found in manifest findingsById/);
require("fs").unlinkSync(tmpManifestPath);
});
// ── Existing --file behaviour unchanged ──
it("existing --file behaviour remains unchanged", async function () {
const fixturePath = require("path").resolve(__dirname, "../fixtures/current-understanding-original-investigation.json");
const result = await runCUExperiment(fixturePath, false, false);
expect(result.success).toBe(true);
expect(result.mode).toBe("deterministic-no-network");
expect(result.findingsCount).toBe(9);
expect(result.fixtureNodes).toBe(11);
expect(result.fixtureEdges).toBe(10);
expect(result.synthesisInvocations).toBe(1);
expect(result.rule2Present).toBe(true);
});
// ── --include-output compatible with checkpoint selection ──
it("--include-output remains compatible with checkpoint selection", async function () {
const manifestPath = require("path").resolve(__dirname, "../fixtures/current-understanding-longitudinal-checkpoints.json");
// Test that runCUExperiment with checkpointManifestPath enters checkpoint mode correctly
// and that includeOutput adds the currentUnderstanding field.
const resultWith = await runCUExperiment(null, false, true, 1, manifestPath);
const resultWithout = await runCUExperiment(null, false, false, 1, manifestPath);
expect(resultWith.success).toBe(true);
expect(resultWithout.success).toBe(true);
expect(resultWith.findingsCount).toBe(2);
expect(resultWithout.findingsCount).toBe(2);
expect(resultWith.synthesisInvocations).toBe(1);
expect(resultWithout.synthesisInvocations).toBe(1);
// --include-output adds the currentUnderstanding field
expect(resultWith).toHaveProperty("currentUnderstanding");
expect(typeof resultWith.currentUnderstanding).toBe("string");
});
// ── Checkpoint selection does not mutate source fixtures ──
it("checkpoint selection does not mutate the original investigation fixture", async function () {
const originalFixturePath = require("path").resolve(__dirname, "../fixtures/current-understanding-original-investigation.json");
const fsModule = require("fs");
const contentBefore = fsModule.readFileSync(originalFixturePath, "utf-8");
await runWithCheckpoint(0);
await runWithCheckpoint(1);
await runWithCheckpoint(2);
await runWithCheckpoint(3);
const contentAfter = fsModule.readFileSync(originalFixturePath, "utf-8");
expect(contentBefore).toBe(contentAfter);
});
it("checkpoint selection does not mutate the longitudinal manifest", async function () {
const manifestPath = require("path").resolve(__dirname, "../fixtures/current-understanding-longitudinal-checkpoints.json");
const fsModule = require("fs");
const contentBefore = fsModule.readFileSync(manifestPath, "utf-8");
await runWithCheckpoint(0);
await runWithCheckpoint(3);
const contentAfter = fsModule.readFileSync(manifestPath, "utf-8");
expect(contentBefore).toBe(contentAfter);
});
});
// ── --include-output flag verification ──
describe("CU synthesis experiment helper — --include-output flag", function () {