Files
confidence-engine/tests/experimental/rto-real-fixture-apparatus.test.js

177 lines
7.5 KiB
JavaScript

/**
* RTO.A4 — Real captured fixture apparatus verification.
*
* Proves the bounded projection boundary:
* 1. source fixture is the real captured JSON
* 2. projected situationGraph is the captured updatedSituationGraph
* 3. exactly 3 unresolved unknowns are derived from real graph state
* 4. their IDs/labels match the captured nodes
* 5. recommended item derives from selectedQuestion.nodeId
* 6. diagnostics recommendation agrees for this fixture
* 7. no synthetic availableThreads/recommendedThreadId data is required
* 8. any presentation selection remains outside situationGraph
* 9. active/reasoning ownership fields are not mutated
*/
import { describe, it, expect } from "vitest";
import rawFixture from "../fixtures/live-product-launch-update-response.json";
import { buildScenarioFixture } from "@/lib/mocks/scenarios.js";
const projected = buildScenarioFixture("rto-real-product-launch", 0);
describe("RTO.A4 real captured fixture apparatus", () => {
/* ── 1. Source fixture is the real captured JSON ─────────── */
it("uses the live-product-launch-update-response.json as source", () => {
expect(projected._sourceFixturePath).toBe("../../tests/fixtures/live-product-launch-update-response.json");
});
/* ── 2. Projected situationGraph is the captured updatedSituationGraph ─── */
it("projects situationGraph from fixture.updatedSituationGraph", () => {
// projected.situationGraph is the SAME object as projected.updatedSituationGraph (alias)
expect(projected.situationGraph).toBe(projected.updatedSituationGraph);
});
it("preserves centralStatement from captured graph", () => {
expect(projected.situationGraph.centralStatement.length).toBeGreaterThan(100);
});
/* ── 3. Exactly 3 unresolved unknowns derived from real graph state ─── */
it("derives exactly 3 unresolved unknowns", () => {
const unresolved = projected.situationGraph.nodes.filter(
(n) => n.kind === "unknown" && n.status !== "resolved"
);
expect(unresolved.length).toBe(3);
});
/* ── 4. IDs/labels match the captured nodes ──────────────── */
it("resolves to the three known unresolved node IDs", () => {
const resolved = JSON.stringify(rawFixture.updatedSituationGraph.nodes
.filter(n => n.kind === "unknown" && n.status !== "resolved")
.map(n => n.id)
.sort());
expect(resolved).toBe(JSON.stringify(["nR4vL9w", "ntpt9ki", "nxmeiab"].sort()));
});
it("labels come directly from captured nodes, not synthesized", () => {
const unresolved = projected.situationGraph.nodes.filter(
(n) => n.kind === "unknown" && n.status !== "resolved"
);
const labels = unresolved.map((n) => n.label);
expect(labels).toContain(
"Probability or current status of the large enterprise customer signing their contract before launch or within the year"
);
expect(labels).toContain(
"Whether competitors are actively developing similar products and how soon they might release them"
);
expect(labels).toContain(
"Sufficiency of committed or highly probable revenue from other customers to cover £300k cost and yield acceptable return"
);
});
/* ── 5. Recommended item derives from selectedQuestion.nodeId ─── */
it("derives recommendation from selectedQuestion.nodeId", () => {
expect(projected.selectedQuestion.nodeId).toBe("nR4vL9w");
});
it("recommendation matches one of the unresolved graph nodes", () => {
const resolved = projected.situationGraph.nodes.find(
(n) => n.id === projected.selectedQuestion.nodeId && n.kind === "unknown"
);
expect(resolved).toBeDefined();
expect(resolved.label).toContain("Sufficiency of committed or highly probable revenue");
});
/* ── 6. Diagnostics recommendation agrees for this fixture ── */
it("diagnostics.unknownSelectionExplanation.selectedNodeId agrees with selectedQuestion", () => {
expect(projected.diagnostics.unknownSelectionExplanation.selectedNodeId).toBe("nR4vL9w");
expect(projected.selectedQuestion.nodeId).toBe(
projected.diagnostics.unknownSelectionExplanation.selectedNodeId
);
});
/* ── 7. No synthetic availableThreads/recommendedThreadId required ─── */
it("does not require synthetic reasoning fields to establish the open set", () => {
// The open set comes from situationGraph.nodes, not from synthetic data
const graphUnknowns = projected.situationGraph.nodes.filter(
(n) => n.kind === "unknown" && n.status !== "resolved"
);
expect(graphUnknowns.length).toBe(3);
// No _experimental or synthetic thread fields on situationGraph
expect(projected.situationGraph._experimental).toBeUndefined();
});
it("does not introduce synthetic recommendationOrder, questionFrame, thread confidence, or priority", () => {
const unresolved = projected.situationGraph.nodes.filter(
(n) => n.kind === "unknown" && n.status !== "resolved"
);
for (const node of unresolved) {
expect(node).not.toHaveProperty("recommendationOrder");
expect(node).not.toHaveProperty("questionFrame");
}
});
/* ── 8. Presentation selection remains outside situationGraph ── */
it("keeps presentation-only state separate from situationGraph", () => {
expect(projected.situationGraph.selectedPresentationItemId).toBeUndefined();
});
it("activeUnknownNodeId is not mutated by the projection", () => {
expect(projected.situationGraph.activeUnknownNodeId).toBe(
rawFixture.updatedSituationGraph.activeUnknownNodeId
);
});
it("selectedQuestion is preserved as captured, not rewritten", () => {
// selectedQuestion comes directly from the fixture — check key fields
expect(projected.selectedQuestion.nodeId).toBe(rawFixture.selectedQuestion.nodeId);
expect(projected.selectedQuestion.question).toBe(rawFixture.selectedQuestion.question);
});
/* ── 9. No production reasoning or ownership mutation ─────── */
it("does not modify activeUnknownNodeId for presentation selection", () => {
const resolved = projected.situationGraph.resolvedNodeIds || [];
expect(resolved).toEqual([]);
});
it("resolvedNodeIds matches captured state (empty)", () => {
const resolved = projected.situationGraph.resolvedNodeIds || [];
expect(resolved.length).toBe(0);
});
/* ── Additional boundary checks ─────────────────────────── */
it("preserves success and stage from fixture", () => {
expect(projected.success).toBe(true);
expect(projected.stage).toBe("update_applied");
});
it("newlySurfacedNodeIds derives from proposal.addedNodes (unknown kind)", () => {
const expected = rawFixture.proposal.addedNodes
.filter(n => n.kind === "unknown")
.map(n => n.id);
expect(projected.newlySurfacedNodeIds).toEqual(expected);
});
it("selectedQuestion matches captured field exactly", () => {
expect(projected.selectedQuestion.nodeId).toBe(rawFixture.selectedQuestion.nodeId);
expect(projected.selectedQuestion.question).toBe(rawFixture.selectedQuestion.question);
});
it("diagnostics object matches captured diagnostics key fields", () => {
expect(projected.diagnostics.promptVersion).toBe(rawFixture.diagnostics.promptVersion);
expect(projected.diagnostics.modelName).toBe(rawFixture.diagnostics.modelName);
expect(projected.diagnostics.validationStatus).toBe(rawFixture.diagnostics.validationStatus);
expect(projected.diagnostics.nodeCount).toBe(rawFixture.diagnostics.nodeCount);
});
});