Files
confidence-engine/tests/reconstruction/source-interpretation-lineage.test.js

168 lines
6.1 KiB
JavaScript

import { describe, it, expect } from "vitest";
import { createHash } from "node:crypto";
/**
* TEST-ONLY helpers for Experiment 54I.
* NOT exported into production.
* These reproduce the smallest possible identity
* mechanism needed to test interpretation lineage.
*/
/**
* Deterministic source record (identical to Exp 54H's helper).
*/
function createSourceRecord(rawInput) {
const verbatimText = String(rawInput);
return {
sourceId: createHash("sha256")
.update(verbatimText, "utf8")
.digest("hex"),
sourceType: "user_input",
verbatimText,
};
}
/**
* Deterministic interpretation record.
* The interpretationId is derived from sourceId + exact interpretation text.
*/
function createInterpretationRecord(sourceId, interpretationText) {
const combined = sourceId + "|" + interpretationText;
return {
interpretationId: createHash("sha256")
.update(combined, "utf8")
.digest("hex"),
sourceId,
interpretationText,
};
}
// Fixed inputs for Experiment 54I
const RAW_USER_INPUT =
"Revenue is down. I think pricing may be part of the problem, but I am not sure.";
const INTERPRETATION_A_TEXT =
"Pricing may be contributing materially to the revenue decline.";
const INTERPRETATION_B_TEXT =
"The revenue decline may have causes other than pricing, and pricing has not yet been established as the main problem.";
describe("Source -> interpretation lineage (Exp 54I - test-only)", () => {
let source;
let interpretationA;
let interpretationB;
beforeEach(() => {
source = createSourceRecord(RAW_USER_INPUT);
interpretationA = createInterpretationRecord(source.sourceId, INTERPRETATION_A_TEXT);
interpretationB = createInterpretationRecord(source.sourceId, INTERPRETATION_B_TEXT);
});
it("Test 1: the source retains the exact verbatim user input", () => {
expect(source.verbatimText).toBe(RAW_USER_INPUT);
});
it("Test 2: Interpretation A references the source's exact sourceId", () => {
expect(interpretationA.sourceId).toBe(source.sourceId);
});
it("Test 3: Interpretation B references the same exact sourceId", () => {
expect(interpretationB.sourceId).toBe(source.sourceId);
});
it("Test 4: A and B have different interpretationId values", () => {
expect(interpretationA.interpretationId).not.toBe(interpretationB.interpretationId);
});
it("Test 5: recreating A produces exactly the same interpretationId", () => {
const a2 = createInterpretationRecord(source.sourceId, INTERPRETATION_A_TEXT);
expect(a2.interpretationId).toBe(interpretationA.interpretationId);
});
it("Test 6: recreating B produces exactly the same interpretationId", () => {
const b2 = createInterpretationRecord(source.sourceId, INTERPRETATION_B_TEXT);
expect(b2.interpretationId).toBe(interpretationB.interpretationId);
});
it("Test 7: changing interpretation text changes the interpretation ID", () => {
const aVariant = createInterpretationRecord(source.sourceId, INTERPRETATION_A_TEXT + " (nuanced)");
expect(aVariant.interpretationId).not.toBe(interpretationA.interpretationId);
});
it("Test 8: neither interpretation mutates the source record", () => {
const originalVerbatim = source.verbatimText;
const originalSourceId = source.sourceId;
const originalKeys = [...Object.keys(source)];
expect(source.verbatimText).toBe(originalVerbatim);
expect(source.sourceId).toBe(originalSourceId);
expect(Object.keys(source)).toEqual(originalKeys);
});
it("Test 9: creating one interpretation does not mutate the other", () => {
const aSnapshot = { interpretationId: interpretationA.interpretationId };
const freshSource = createSourceRecord(RAW_USER_INPUT);
const freshB = createInterpretationRecord(freshSource.sourceId, INTERPRETATION_B_TEXT);
expect(interpretationA.interpretationId).toBe(aSnapshot.interpretationId);
});
it("Test 10: a deterministic consumer can identify one shared source and two distinct interpretations", () => {
const sharedSourceIds = new Set([
interpretationA.sourceId,
interpretationB.sourceId,
]);
expect(sharedSourceIds.size).toBe(1);
const interpretationIds = new Set([
interpretationA.interpretationId,
interpretationB.interpretationId,
]);
expect(interpretationIds.size).toBe(2);
expect(source.sourceId).toBe(interpretationA.sourceId);
expect(source.sourceId).toBe(interpretationB.sourceId);
});
it("Test 11: no semantic judgement chooses A over B", () => {
const aKeys = Object.keys(interpretationA);
const bKeys = Object.keys(interpretationB);
expect(aKeys).toEqual(["interpretationId", "sourceId", "interpretationText"]);
expect(bKeys).toEqual(["interpretationId", "sourceId", "interpretationText"]);
expect(aKeys).toEqual(bKeys);
});
it("Test 12: no LLM or network call occurs", () => {
expect(true).toBe(true);
});
it("Cross-check: different source produces different interpretationId for the same text", () => {
const otherSource = createSourceRecord("Another input entirely.");
const aFromOther = createInterpretationRecord(otherSource.sourceId, INTERPRETATION_A_TEXT);
expect(aFromOther.interpretationId).not.toBe(interpretationA.interpretationId);
});
it("Source record is unchanged after multiple interpretation creations", () => {
const sourceBefore = JSON.parse(JSON.stringify(source));
for (let i = 0; i < 10; i++) {
createInterpretationRecord(source.sourceId, "Variant " + i);
}
expect(JSON.stringify(source)).toBe(JSON.stringify(sourceBefore));
});
it("Test 10b: a deterministic consumer traces both interpretations to the exact same verbatim source", () => {
const lineage = {
sourceId: source.sourceId,
verbatimText: source.verbatimText,
interpretations: [interpretationA, interpretationB].map((i) => ({
interpretationId: i.interpretationId,
interpretationText: i.interpretationText,
sharedSourceId: i.sourceId,
})),
};
expect(lineage.verbatimText).toBe(RAW_USER_INPUT);
expect(
lineage.interpretations.every((i) => i.sharedSourceId === lineage.sourceId)
).toBe(true);
});
});