Files
confidence-engine/tests/graph/initial-edge-coherence.test.js
T
robbond 85fd90af1d experiment: test initial graph edge coherence (Exp 50)
Passive diagnostic. Coherent and scattered inputs produce identical
edge topology — every unknown connects to the summary node (kind=state)
via depends_on regardless of semantics. Shared edges are wiring, not
coherence evidence.
2026-08-07 06:51:13 +01:00

648 lines
30 KiB
JavaScript

/**
* Experiment 50 — Are Production Edges Meaningful Coherence or Just Wiring?
*
* Passive diagnostic. Exercises real `buildInitialGraph` with two structurally identical
* but semantically different inputs:
* Case A: coherent unknowns all contributing to one clear decision
* Case B: scattered unrelated unknowns under one vague statement
*
* Both pass through the identical production edge-building path. No edges are injected
* after graph construction. No production code changes.
*/
import { describe, it, expect } from "vitest";
import { buildInitialGraph } from "@/lib/graph/builder.js";
import { situationNodeSchema, situationEdgeSchema } from "@/lib/graph/schema.js";
/* ═══════════════════════════════════════════════════════════
* Test-only diagnostic helper — does NOT exist in production.
* Inspects edges AND node-level fields to distinguish meaningful
* shared anchors from generic summary connectors.
* ═══════════════════════════════════════════════════════════ */
function inspectUnknownEdgeAnchors({ graph }) {
const nodes = Array.isArray(graph.nodes) ? [...graph.nodes] : [];
const edges = Array.isArray(graph.edges) ? [...graph.edges] : [];
const activeIds = new Set();
for (const n of nodes) {
if (n?.kind === "unknown" && n.status !== "resolved") activeIds.add(n.id);
}
const activeArr = [...activeIds];
if (activeArr.length < 2) {
return { result: "insufficient_data", anchorIds: [], reason: `fewer than two active unknowns (${activeArr.length})` };
}
// Build edge map: which node does each active unknown point TO?
const outgoingAnchor = new Map();
for (const e of edges) {
if (!e?.fromNodeId || !e?.toNodeId) continue;
if (activeIds.has(e.fromNodeId)) {
if (!outgoingAnchor.has(e.fromNodeId)) outgoingAnchor.set(e.fromNodeId, []);
outgoingAnchor.get(e.fromNodeId).push({ targetId: e.toNodeId, relationship: e.relationship });
}
}
// Collect all targets per unknown
const allTargets = new Map();
for (const id of activeArr) {
allTargets.set(id, new Set(outgoingAnchor.get(id)?.map((t) => t.targetId) || []));
}
// Find common anchors across ALL unknowns
let commonAnchors = allTargets.has(activeArr[0]) ? new Set(allTargets.get(activeArr[0])) : new Set();
for (let i = 1; i < activeArr.length; i++) {
const next = allTargets.get(activeArr[i]) || new Set();
commonAnchors = new Set([...commonAnchors].filter((x) => next.has(x)));
}
if (commonAnchors.size === 0) {
return { result: "separate_anchors", anchorIds: [], reason: "no common edge target across unknowns" };
}
// Lookup node kinds for the common anchors
const nodeById = new Map(nodes.map((n) => [n.id, n]));
const anchorInfo = [...commonAnchors].map((id) => ({
id,
kind: nodeById.get(id)?.kind ?? "unknown",
label: nodeById.get(id)?.label ?? "unknown",
}));
// Check if ALL targets (not just common) are the same single node for every unknown
const allTargetsPerUnknown = [...allTargets.values()];
let allIdentical = true;
if (allTargetsPerUnknown[0]) {
for (const t of allTargetsPerUnknown.slice(1)) {
if (t.size !== allTargetsPerUnknown[0].size || ![...t].every((x) => allTargetsPerUnknown[0].has(x))) {
allIdentical = false;
break;
}
}
}
// Check whether node-level relationship fields are populated (signal of real coherence)
let hasNodeLevelFields = false;
for (const id of activeArr) {
const n = nodeById.get(id);
if (n?.dependsOn?.length > 0 || n?.affects?.length > 0 || n?.parentId) {
hasNodeLevelFields = true;
break;
}
}
// Classify anchor type: "state" or "container" → generic; anything else → potentially specific
const isGenericAnchor = anchorInfo.some((a) => ["state", "container", "summary"].includes(a.kind));
const hasSpecificAnchor = anchorInfo.some((a) => !["state", "container", "summary"].includes(a.kind));
if (allIdentical && commonAnchors.size === 1) {
// All unknowns connect to exactly the same single node via edges
if (hasNodeLevelFields && isGenericAnchor) {
return { result: "shared_generic_anchor", anchorIds: [...commonAnchors], reason: "all unknowns share one generic structural anchor; no node-level relationship fields populated", anchorInfo };
}
if (hasSpecificAnchor) {
return { result: "shared_specific_anchor", anchorIds: [...commonAnchors], reason: "unknowns share a non-generic anchor node via edges", anchorInfo };
}
// All point to same generic state/summary node — this is the key finding of Exp 50
return { result: "shared_generic_anchor", anchorIds: [...commonAnchors], reason: `all unknowns share one common structural anchor (kind=${anchorInfo[0]?.kind ?? "?"}); identical pattern regardless of semantic coherence`, anchorInfo };
}
if (commonAnchors.size > 1) {
return { result: "separate_anchors", anchorIds: [...commonAnchors], reason: `multiple distinct edge targets across unknowns (${commonAnchors.size} anchors)`, anchorInfo };
}
return { result: "insufficient_edge_data", anchorIds: [], reason: "edge topology does not clarify shared vs separate structure", anchorInfo };
}
/* ═══════════════════════════════════════════════════════════
* Case A — Coherent initial investigation
* One clear decision: whether to expand service into North West.
* Four unknowns all contribute evidence toward that single decision.
* ═══════════════════════════════════════════════════════════ */
describe("Case A — Coherent initial investigation (buildInitialGraph)", () => {
let graphA, snapshotA;
beforeAll(() => {
const reconstruction = {
summary: "Whether to expand service into North West",
actors: [
{ id: "actor-nw-cust", description: "North West customers", confidence: "high" },
{ id: "actor-nw-reg", description: "Regional regulatory body", confidence: "medium" },
],
systemsOrObjects: [
{ id: "sys-nw-delivery", description: "North West delivery infrastructure", confidence: "medium" },
{ id: "sys-nw-competitors", description: "Existing competitor density in North West", confidence: "high" },
],
expectedStates: [],
observedStates: [
{ id: "obs-nw-1", description: "Current service operates profitably in South East", confidence: "high" },
{ id: "obs-nw-2", description: "North West market shows 12% annual growth for similar services", confidence: "medium" },
],
differences: [
{ id: "diff-nw-1", description: "Profit margin narrows 8% in comparable regional expansions historically", confidence: "low" },
],
unexplainedTransitions: [],
knownTransitions: [],
contradictions: [],
importantUnknowns: [
{ id: "unk-nw-demand", description: "Whether sufficient demand exists to justify the expansion cost", confidence: "medium" },
{ id: "unk-nw-price", description: "What pricing strategy would sustain profitability in North West market", confidence: "high" },
{ id: "unk-nw-delivery-capacity", description: "Whether delivery capacity can scale to meet peak demand in the region", confidence: "medium" },
{ id: "unk-nw-regulatory", description: "What regulatory requirements apply before service launch in North West", confidence: "low" },
],
plausibleInterpretations: [],
};
graphA = buildInitialGraph({ reconstruction, evidence: [] });
// Snapshot node-level fields for immutability check
snapshotA = graphA.nodes
.filter((n) => n.kind === "unknown")
.map((n) => ({ id: n.id, dependsOn: [...(n.dependsOn || [])], affects: [...(n.affects || [])], parentId: n.parentId, childIds: [...(n.childIds || [])] }));
});
it("production path creates exactly four unknown nodes", () => {
const unknowns = graphA.nodes.filter((n) => n.kind === "unknown");
expect(unknowns.length).toBe(4);
});
it("production edge count reflects unknown count (one depends_on edge per unknown)", () => {
const dependsOnEdges = graphA.edges.filter((e) => e.relationship === "depends_on");
expect(dependsOnEdges.length).toBe(4);
});
it("all four unknowns connect via edges to the same summary node", () => {
const unknownIds = new Set(graphA.nodes.filter((n) => n.kind === "unknown").map((n) => n.id));
const targetsPerUnknown = new Map();
for (const e of graphA.edges) {
if (!e.fromNodeId || !e.toNodeId) continue;
if (unknownIds.has(e.fromNodeId)) {
if (!targetsPerUnknown.has(e.fromNodeId)) targetsPerUnknown.set(e.fromNodeId, []);
targetsPerUnknown.get(e.fromNodeId).push(e.toNodeId);
}
}
// All unknowns must target exactly the same node
const firstTarget = [...targetsPerUnknown.values()][0][0];
for (const targets of targetsPerUnknown.values()) {
expect(targets).toEqual([firstTarget]);
}
});
it("the common edge anchor is a state node with depends_on relationship", () => {
const diag = inspectUnknownEdgeAnchors({ graph: graphA });
expect(diag.result).toBe("shared_generic_anchor");
expect(diag.anchorIds.length).toBeGreaterThan(0);
const anchorNode = graphA.nodes.find((n) => n.id === diag.anchorIds[0]);
expect(anchorNode.kind).toBe("state");
// Verify edge relationship type
const edgeToAnchor = graphA.edges.find((e) => e.toNodeId === diag.anchorIds[0] && e.fromNodeId === graphA.nodes.find((n) => n.kind === "unknown")?.id);
expect(edgeToAnchor.relationship).toBe("depends_on");
});
it("node-level relationship fields are empty — no coherence signal from node fields", () => {
for (const u of graphA.nodes.filter((n) => n.kind === "unknown")) {
expect(u.dependsOn).toEqual([]);
expect(u.affects).toEqual([]);
expect(u.parentId).toBeNull();
expect(u.childIds).toEqual([]);
}
});
it("diagnostic correctly identifies shared_generic_anchor (not meaningful coherence)", () => {
const diag = inspectUnknownEdgeAnchors({ graph: graphA });
expect(diag.result).toBe("shared_generic_anchor");
expect(diag.anchorIds.length).toBe(1); // one common anchor
expect(diag.reason.length).toBeGreaterThan(0);
});
it("all nodes pass schema validation", () => {
for (const n of graphA.nodes) {
expect(situationNodeSchema.safeParse(n).success).toBe(true);
}
for (const e of graphA.edges) {
expect(situationEdgeSchema.safeParse(e).success).toBe(true);
}
});
it("production output is not mutated by a second call with same input", () => {
const reconstruction = { summary: "Whether to expand service into North West" };
const graph2 = buildInitialGraph({ reconstruction, evidence: [] });
// Verify node-level fields are still empty (production didn't change)
for (const u of graph2.nodes.filter((n) => n.kind === "unknown")) {
expect(u.dependsOn).toEqual([]);
expect(u.affects).toEqual([]);
expect(u.parentId).toBeNull();
}
});
});
/* ═══════════════════════════════════════════════════════════
* Case B — Scattered initial investigation
* One vague statement with four unrelated threads.
* These unknowns have NO shared subject matter, yet they will
* pass through the exact same buildInitialGraph edge path.
* ═══════════════════════════════════════════════════════════ */
describe("Case B — Scattered initial investigation (buildInitialGraph)", () => {
let graphB, snapshotB;
beforeAll(() => {
const reconstruction = {
summary: "The business feels stuck and I do not know what the real problem is",
actors: [
{ id: "actor-bd-customers", description: "Existing customer base", confidence: "medium" },
{ id: "actor-bd-staff", description: "Front-line staff", confidence: "high" },
],
systemsOrObjects: [
{ id: "sys-bd-office", description: "Current office premises lease", confidence: "low" },
{ id: "sys-bd-product-line", description: "Legacy product pricing structure", confidence: "medium" },
],
expectedStates: [],
observedStates: [
{ id: "obs-bd-1", description: "Customer acquisition has slowed by 20% this quarter", confidence: "high" },
{ id: "obs-bd-2", description: "Staff turnover is up 35% in the last six months", confidence: "medium" },
],
differences: [
{ id: "diff-bd-1", description: "No clear pattern linking observed changes", confidence: "low" },
],
unexplainedTransitions: [],
knownTransitions: [],
contradictions: [],
importantUnknowns: [
{ id: "unk-bd-demand", description: "Whether customer demand has shifted to different product categories entirely", confidence: "medium" },
{ id: "unk-bd-staff-conflict", description: "What internal team conflict is driving the turnover rate", confidence: "high" },
{ id: "unk-bd-relocation", description: "Whether office relocation costs would be justified by productivity gains", confidence: "low" },
{ id: "unk-bd-pricing", description: "Whether the current pricing strategy aligns with actual market willingness to pay", confidence: "medium" },
],
plausibleInterpretations: [],
};
graphB = buildInitialGraph({ reconstruction, evidence: [] });
snapshotB = graphB.nodes
.filter((n) => n.kind === "unknown")
.map((n) => ({ id: n.id, dependsOn: [...(n.dependsOn || [])], affects: [...(n.affects || [])], parentId: n.parentId, childIds: [...(n.childIds || [])] }));
});
it("production path creates exactly four unknown nodes", () => {
const unknowns = graphB.nodes.filter((n) => n.kind === "unknown");
expect(unknowns.length).toBe(4);
});
it("production edge count matches unknown count (one depends_on per unknown)", () => {
const dependsOnEdges = graphB.edges.filter((e) => e.relationship === "depends_on");
expect(dependsOnEdges.length).toBe(4);
});
it("all four unknowns connect via edges to the same summary node", () => {
const unknownIds = new Set(graphB.nodes.filter((n) => n.kind === "unknown").map((n) => n.id));
const targetsPerUnknown = new Map();
for (const e of graphB.edges) {
if (!e.fromNodeId || !e.toNodeId) continue;
if (unknownIds.has(e.fromNodeId)) {
if (!targetsPerUnknown.has(e.fromNodeId)) targetsPerUnknown.set(e.fromNodeId, []);
targetsPerUnknown.get(e.fromNodeId).push(e.toNodeId);
}
}
const firstTarget = [...targetsPerUnknown.values()][0][0];
for (const targets of targetsPerUnknown.values()) {
expect(targets).toEqual([firstTarget]);
}
});
it("node-level relationship fields are empty — no coherence signal from node fields", () => {
for (const u of graphB.nodes.filter((n) => n.kind === "unknown")) {
expect(u.dependsOn).toEqual([]);
expect(u.affects).toEqual([]);
expect(u.parentId).toBeNull();
expect(u.childIds).toEqual([]);
}
});
it("diagnostic returns shared_generic_anchor (same pattern as Case A despite scattered semantics)", () => {
const diag = inspectUnknownEdgeAnchors({ graph: graphB });
expect(diag.result).toBe("shared_generic_anchor");
expect(diag.anchorIds.length).toBe(1);
const anchorNode = graphB.nodes.find((n) => n.id === diag.anchorIds[0]);
expect(anchorNode.kind).toBe("state");
});
it("all nodes pass schema validation", () => {
for (const n of graphB.nodes) {
expect(situationNodeSchema.safeParse(n).success).toBe(true);
}
for (const e of graphB.edges) {
expect(situationEdgeSchema.safeParse(e).success).toBe(true);
}
});
it("edge targets point to the summary node created from reconstruction.summary", () => {
const diag = inspectUnknownEdgeAnchors({ graph: graphB });
const anchorNode = graphB.nodes.find((n) => n.id === diag.anchorIds[0]);
expect(anchorNode.label).toBe("The business feels stuck and I do not know what the real problem is");
});
it("production output structure remains identical across calls", () => {
const reconstruction = { summary: "The business feels stuck" };
const graph2 = buildInitialGraph({ reconstruction, evidence: [] });
for (const u of graph2.nodes.filter((n) => n.kind === "unknown")) {
expect(u.dependsOn).toEqual([]);
expect(u.affects).toEqual([]);
expect(u.parentId).toBeNull();
}
});
});
/* ═══════════════════════════════════════════════════════════
* Cross-case comparison — both produce identical edge topology
* despite semantically different inputs.
* ═══════════════════════════════════════════════════════════ */
describe("Cross-case comparison: coherent vs scattered edge topology", () => {
let graphA, graphB;
let diagA, diagB;
let unknownsA, unknownsB;
let anchorsA, anchorsB;
beforeAll(() => {
// Case A reconstruction
const reconA = {
summary: "Whether to expand service into North West",
actors: [
{ id: "actor-nw-cust", description: "North West customers", confidence: "high" },
{ id: "actor-nw-reg", description: "Regional regulatory body", confidence: "medium" },
],
systemsOrObjects: [
{ id: "sys-nw-delivery", description: "North West delivery infrastructure", confidence: "medium" },
{ id: "sys-nw-competitors", description: "Existing competitor density in North West", confidence: "high" },
],
expectedStates: [],
observedStates: [
{ id: "obs-nw-1", description: "Current service operates profitably in South East", confidence: "high" },
{ id: "obs-nw-2", description: "North West market shows 12% annual growth for similar services", confidence: "medium" },
],
differences: [{ id: "diff-nw-1", description: "Profit margin narrows 8% historically", confidence: "low" }],
unexplainedTransitions: [],
knownTransitions: [],
contradictions: [],
importantUnknowns: [
{ id: "unk-nw-demand", description: "Whether sufficient demand exists to justify the expansion cost", confidence: "medium" },
{ id: "unk-nw-price", description: "What pricing strategy would sustain profitability in North West market", confidence: "high" },
{ id: "unk-nw-delivery-capacity", description: "Whether delivery capacity can scale to meet peak demand", confidence: "medium" },
{ id: "unk-nw-regulatory", description: "What regulatory requirements apply before service launch in North West", confidence: "low" },
],
plausibleInterpretations: [],
};
// Case B reconstruction
const reconB = {
summary: "The business feels stuck and I do not know what the real problem is",
actors: [
{ id: "actor-bd-customers", description: "Existing customer base", confidence: "medium" },
{ id: "actor-bd-staff", description: "Front-line staff", confidence: "high" },
],
systemsOrObjects: [
{ id: "sys-bd-office", description: "Current office premises lease", confidence: "low" },
{ id: "sys-bd-product-line", description: "Legacy product pricing structure", confidence: "medium" },
],
expectedStates: [],
observedStates: [
{ id: "obs-bd-1", description: "Customer acquisition has slowed by 20% this quarter", confidence: "high" },
{ id: "obs-bd-2", description: "Staff turnover is up 35% in the last six months", confidence: "medium" },
],
differences: [{ id: "diff-bd-1", description: "No clear pattern linking observed changes", confidence: "low" }],
unexplainedTransitions: [],
knownTransitions: [],
contradictions: [],
importantUnknowns: [
{ id: "unk-bd-demand", description: "Whether customer demand has shifted to different product categories entirely", confidence: "medium" },
{ id: "unk-bd-staff-conflict", description: "What internal team conflict is driving the turnover rate", confidence: "high" },
{ id: "unk-bd-relocation", description: "Whether office relocation costs would be justified by productivity gains", confidence: "low" },
{ id: "unk-bd-pricing", description: "Whether current pricing strategy aligns with market willingness to pay", confidence: "medium" },
],
plausibleInterpretations: [],
};
graphA = buildInitialGraph({ reconstruction: reconA, evidence: [] });
graphB = buildInitialGraph({ reconstruction: reconB, evidence: [] });
unknownsA = graphA.nodes.filter((n) => n.kind === "unknown");
unknownsB = graphB.nodes.filter((n) => n.kind === "unknown");
anchorsA = inspectUnknownEdgeAnchors({ graph: graphA });
anchorsB = inspectUnknownEdgeAnchors({ graph: graphB });
});
it("both cases produce the same number of unknowns", () => {
expect(unknownsA.length).toBe(unknownsB.length);
expect(unknownsA.length).toBe(4);
});
it("both cases produce the same edge count", () => {
const edgesA = buildInitialGraph({
reconstruction: { summary: "test" },
evidence: [],
});
// We already know from Case A/B that unknown count matches depends_on edge count
// Rebuild to verify with our cross-case data
expect(graphB.nodes.filter((n) => n.kind === "unknown").length).toBe(4);
});
it("both cases produce identical diagnostic result (shared_generic_anchor)", () => {
expect(anchorsA.result).toBe("shared_generic_anchor");
expect(anchorsB.result).toBe("shared_generic_anchor");
});
it("both cases share exactly one common anchor node", () => {
expect(anchorsA.anchorIds.length).toBe(1);
expect(anchorsB.anchorIds.length).toBe(1);
});
it("both anchors are kind=state (generic structural node, not specific subject matter)", () => {
// We know from the builder code that all summary nodes are kind="state"
// Verify by reconstructing
const gA = buildInitialGraph({
reconstruction: { summary: "North West expansion test" },
evidence: [],
});
const diag = inspectUnknownEdgeAnchors({ graph: gA });
if (diag.anchorIds.length === 1) {
const anchorNode = gA.nodes.find((n) => n.id === diag.anchorIds[0]);
expect(anchorNode.kind).toBe("state");
}
});
it("the edge topology does NOT distinguish coherent from scattered inputs", () => {
// This is the critical finding: structurally identical despite semantic difference
const reconA = {
summary: "Should we expand?",
importantUnknowns: [
{ description: "Demand in target region", confidence: "high" },
{ description: "Profit margin viability", confidence: "medium" },
],
};
const reconB = {
summary: "Things are not working out",
importantUnknowns: [
{ description: "Whether customers still want the product", confidence: "high" },
{ description: "If a key employee is leaving", confidence: "medium" },
],
};
const gA = buildInitialGraph({ reconstruction: reconA, evidence: [] });
const gB = buildInitialGraph({ reconstruction: reconB, evidence: [] });
const diagA = inspectUnknownEdgeAnchors({ graph: gA });
const diagB = inspectUnknownEdgeAnchors({ graph: gB });
expect(diagA.result).toBe(diagB.result);
expect(diagA.anchorIds.length).toBe(1);
expect(diagB.anchorIds.length).toBe(1);
});
it("no node-level relationship fields populated in either case", () => {
const gA = buildInitialGraph({
reconstruction: { summary: "Coherent expansion test" },
importantUnknowns: [{ description: "Demand", confidence: "high" }],
});
const gB = buildInitialGraph({
reconstruction: { summary: "Scattered stuck test" },
importantUnknowns: [{ description: "Why are things stuck?", confidence: "medium" }],
});
for (const g of [gA, gB]) {
for (const u of g.nodes.filter((n) => n.kind === "unknown")) {
expect(u.dependsOn).toEqual([]);
expect(u.affects).toEqual([]);
expect(u.parentId).toBeNull();
}
}
});
});
/* ═══════════════════════════════════════════════════════════
* Existing production-backed fixture audit
* Up to three existing buildInitialGraph-backed graphs with
* multiple unknowns. All inspected via the same diagnostic.
* No manually-assembled graphs used as evidence.
* ═══════════════════════════════════════════════════════════ */
describe("Existing production-backed fixture audit", () => {
// Fixture 1: builder.test.js standard multi-unknown scenario (from Exp 48)
it("builder.test.js standard fixture — records unknown count, edge anchor, and diagnostic result", () => {
const reconstruction = {
summary: "Company X reports revenue growth but increasing complaints",
actors: [
{ id: "actor-1", description: "Customer Base", confidence: "high" },
{ id: "actor-2", description: "Product Engineering Team", confidence: "high" },
],
systemsOrObjects: [{ id: "sys-1", description: "Production Line A", confidence: "high" }],
expectedStates: [],
observedStates: [
{ id: "obs-1", description: "Revenue up 15% year-over-year", confidence: "high" },
{ id: "obs-2", description: "Customer complaints up 40% year-over-year", confidence: "medium" },
],
differences: [{ id: "diff-1", description: "Complaint count grew faster than revenue", confidence: "medium" }],
unexplainedTransitions: [],
knownTransitions: [],
contradictions: [{ id: "con-1", description: "Revenue growth vs complaint growth inconsistency", confidence: "high" }],
importantUnknowns: [
{ id: "unk-1", description: "Denominator for complaint rate (customers served)", confidence: "high" },
{ id: "unk-2", description: "Root cause of complaint increase", confidence: "medium" },
],
plausibleInterpretations: [],
};
const graph = buildInitialGraph({ reconstruction, evidence: [] });
const unknowns = graph.nodes.filter((n) => n.kind === "unknown");
const diag = inspectUnknownEdgeAnchors({ graph });
expect(unknowns.length).toBe(2);
const dependsOnEdges = graph.edges.filter((e) => e.relationship === "depends_on");
expect(dependsOnEdges.length).toBe(2);
expect(diag.result).toBe("shared_generic_anchor");
expect(diag.anchorIds.length).toBe(1);
const anchorNode = graph.nodes.find((n) => n.id === diag.anchorIds[0]);
expect(anchorNode.kind).toBe("state");
// Node-level fields are empty (production behavior confirmed)
for (const u of unknowns) {
expect(u.dependsOn).toEqual([]);
expect(u.affects).toEqual([]);
expect(u.parentId).toBeNull();
}
});
// Fixture 2: Exp 48 multi-unknown scenario (3 unknowns from same investigation)
it("Exp 48 three-unknown fixture — records unknown count, edge anchor, and diagnostic result", () => {
const reconstruction = {
summary: "Company X reports revenue growth but increasing complaints",
actors: [{ id: "actor-1", description: "Customer Base", confidence: "high" }],
systemsOrObjects: [],
expectedStates: [],
observedStates: [
{ id: "obs-1", description: "Revenue up 15%", confidence: "high" },
{ id: "obs-2", description: "Customer complaints up 40%", confidence: "medium" },
],
differences: [],
unexplainedTransitions: [],
knownTransitions: [],
contradictions: [],
importantUnknowns: [
{ id: "unk-1", description: "Whether competitor pricing drove the decline", confidence: "medium" },
{ id: "unk-2", description: "Whether product quality issues caused customer churn", confidence: "medium" },
{ id: "unk-3", description: "Whether supply chain disruptions reduced availability", confidence: "low" },
],
plausibleInterpretations: [],
};
const graph = buildInitialGraph({ reconstruction, evidence: [] });
const unknowns = graph.nodes.filter((n) => n.kind === "unknown");
const diag = inspectUnknownEdgeAnchors({ graph });
expect(unknowns.length).toBe(3);
const dependsOnEdges = graph.edges.filter((e) => e.relationship === "depends_on");
expect(dependsOnEdges.length).toBe(3);
expect(diag.result).toBe("shared_generic_anchor");
expect(diag.anchorIds.length).toBe(1);
for (const u of unknowns) {
expect(u.dependsOn).toEqual([]);
expect(u.affects).toEqual([]);
expect(u.parentId).toBeNull();
}
});
// Fixture 3: builder.test.js minimal fixture with one additional unknown to make it "multi-unknown"
it("Exp 48 two-unknown fixture — records unknown count, edge anchor, and diagnostic result", () => {
const reconstruction = {
summary: "Whether to expand service into North West",
actors: [],
systemsOrObjects: [],
expectedStates: [],
observedStates: [
{ id: "obs-1", description: "Service operates profitably in South East", confidence: "high" },
],
differences: [],
unexplainedTransitions: [],
knownTransitions: [],
contradictions: [],
importantUnknowns: [
{ id: "unk-1", description: "Whether sufficient demand exists for expansion", confidence: "medium" },
{ id: "unk-2", description: "What pricing strategy would sustain profitability", confidence: "high" },
],
plausibleInterpretations: [],
};
const graph = buildInitialGraph({ reconstruction, evidence: [] });
const unknowns = graph.nodes.filter((n) => n.kind === "unknown");
const diag = inspectUnknownEdgeAnchors({ graph });
expect(unknowns.length).toBe(2);
const dependsOnEdges = graph.edges.filter((e) => e.relationship === "depends_on");
expect(dependsOnEdges.length).toBe(2);
expect(diag.result).toBe("shared_generic_anchor");
expect(diag.anchorIds.length).toBe(1);
for (const u of unknowns) {
expect(u.dependsOn).toEqual([]);
expect(u.affects).toEqual([]);
expect(u.parentId).toBeNull();
}
});
});