experiment: derive condition status from answer evidence

This commit is contained in:
2026-08-06 11:17:17 +01:00
parent aabb797e5d
commit da291c715b
3 changed files with 306 additions and 137 deletions
+35 -30
View File
@@ -68,7 +68,8 @@ describe("assessDecisionConditionStatus — established", () => {
expect(result.reason.length).toBeGreaterThan(0);
});
it("returns established when resolved cost evidence supports the value_cost condition", () => {
it("returns unresolved when resolved evidence shows cost but not value justification", () => {
// Cost/compliance investment data is contextual — does not prove value justifies cost.
const graph = makeGraph(
[makeNode("c-1", "Achieving compliance would require $500K and 6 months investment", { status: "resolved" })],
["c-1"],
@@ -79,8 +80,8 @@ describe("assessDecisionConditionStatus — established", () => {
graph,
});
expect(result.status).toBe("established");
expect(result.evidenceNodeIds).toContain("c-1");
expect(result.status).toBe("unresolved");
expect(result.evidenceNodeIds).toHaveLength(0);
});
it("returns established when resolved unique feature evidence supports differentiation", () => {
@@ -164,11 +165,8 @@ describe("assessDecisionConditionStatus — contradicted", () => {
expect(result.status).toBe("contradicted");
});
it("returns established when value_cost evidence shows cost matching (no contradiction phrase)", () => {
// "ROI over five years is not viable" has no CONTRADICTION_PHRASE match
// and "viable" ≠ "viability", so support check finds nothing → should be unresolved
// But the condition CATEGORY_GROUPS["value_cost"] matches via "cost" in condition text
// So we need evidence with a value_cost keyword to establish it
it("returns unresolved when value_cost evidence shows cost matching (no contradiction phrase)", () => {
// Generic cost/investment evidence without a supporting or contradicting phrase stays unresolved
const graph = makeGraph(
[makeNode("v-1", "Achieving compliance would require $500K and 6 months investment", { status: "resolved" })],
["v-1"],
@@ -179,7 +177,8 @@ describe("assessDecisionConditionStatus — contradicted", () => {
graph,
});
expect(result.status).toBe("established");
expect(result.status).toBe("unresolved");
expect(result.evidenceNodeIds).toHaveLength(0);
});
it("returns established when differentiation evidence contains a support keyword", () => {
@@ -428,38 +427,41 @@ describe("assessDecisionConditionStatus — long investigation sequence", () =>
expect(nonUnresolved).toBe(2);
});
it("turn 3 has three conditions established (demand, compliance, value_cost)", () => {
// Turn 3 resolved=[u-1,u-2,u-3]; obs-4 is NOT in resolved set
it("turn 3 has two non-unresolved conditions (demand=established, compliance=contradicted)", () => {
// Turn 3 resolved=[u-1,u-2,u-3]; obs-4 provides contextual info only
const turn3 = allResults.filter((r) => r.turn === 3);
const nonUnresolved = turn3.filter((r) => r.status !== "unresolved").length;
expect(nonUnresolved).toBe(3);
});
expect(nonUnresolved).toBe(2);
it("turn 3 compliance is established (u-2 'compliance' keyword)", () => {
const turn3 = allResults.filter((r) => r.turn === 3);
// Compliance is contradicted (does not support EU data residency)
const complianceResult = turn3.find((r) => r.condition.includes("compliance"));
expect(complianceResult.status).toBe("established");
});
expect(complianceResult.status).toBe("contradicted");
it("turn 3 value_cost is established (u-3 'cost' keyword matches)", () => {
const turn3 = allResults.filter((r) => r.turn === 3);
// Value cost is unresolved (cost evidence only provides context, not justification proof)
const valueCostResult = turn3.find((r) => r.condition.includes("value"));
expect(valueCostResult.status).toBe("established");
expect(valueCostResult.status).toBe("unresolved");
});
it("turn 4 (all resolved) has at least three conditions established", () => {
it("turn 4 has two established and one contradicted", () => {
// Turn 4 resolved=[u-1,u-2,u-3,u-4]
// demand=established, compliance=contradicted, value_cost=unresolved, differentiation=established
const turn4 = allResults.filter((r) => r.turn === 4);
const establishedCount = turn4.filter((r) => r.status === "established").length;
expect(establishedCount).toBeGreaterThanOrEqual(3);
});
expect(establishedCount).toBeGreaterThanOrEqual(2);
it("turn 4 demand is established (u-1 resolved with 'demand' keyword)", () => {
const turn4 = allResults.filter((r) => r.turn === 4);
const contradictedCount = turn4.filter((r) => r.status === "contradicted").length;
expect(contradictedCount).toBeGreaterThanOrEqual(1);
// Demand is established
const demandResult = turn4.find((r) => r.condition.includes("demand"));
expect(demandResult.status).toBe("established");
// Differentiation is established (no direct European equivalent)
const diffResult = turn4.find((r) => r.condition.includes("competitive"));
expect(diffResult.status).toBe("established");
});
it("status transitions make sense: unresolved → established over turns", () => {
it("status transitions make sense: unresolved → determined over turns", () => {
const byCondition = {};
for (const r of allResults) {
if (!byCondition[r.condition]) byCondition[r.condition] = [];
@@ -467,6 +469,11 @@ describe("assessDecisionConditionStatus — long investigation sequence", () =>
}
for (const [cond, turns] of Object.entries(byCondition)) {
// Only check transitions for conditions that are never fully unresolved
// (value_cost may always be unresolved if evidence is contextual only)
const hasNonUnresolved = turns.some((t) => t.status !== "unresolved");
if (!hasNonUnresolved) continue;
let hadUnresolvedFirst = false;
for (let i = 0; i < turns.length - 1; i++) {
if (turns[i].status === "unresolved") hadUnresolvedFirst = true;
@@ -479,12 +486,10 @@ describe("assessDecisionConditionStatus — long investigation sequence", () =>
}
});
it("condition evidenceNodeIds is non-empty when status is established", () => {
it("condition evidenceNodeIds reflects linked observations for resolved unknowns", () => {
for (const r of allResults) {
if (r.status === "established") {
if ((r.status === "established" || r.status === "contradicted")) {
expect(r.evidenceNodeIds.length).toBeGreaterThan(0);
} else if (r.status === "unresolved") {
expect(r.evidenceNodeIds.length).toBe(0);
}
}
});