feat(reasoning): add decision materiality rule

This commit is contained in:
2026-08-13 07:24:16 +01:00
parent 5dcaed39df
commit 5ce5e7349b
2 changed files with 107 additions and 0 deletions
+99
View File
@@ -764,3 +764,102 @@ describe("60A.3 decision option prompt rules", () => {
expect(altLine).toBeDefined();
});
});
// ── Experiment 60B.4 — Decision Materiality Rule ──────────────
describe("60B.4 decision materiality rule", () => {
const prompt = buildGraphUpdatePrompt(makeContext());
it("rule: unresolved decision not kept open merely because uncertainty remains", () => {
expect(prompt).toContain(
"should not remain open merely because some uncertainty still exists",
);
});
it("rule: continuation requires a specific unresolved factor", () => {
expect(prompt).toContain("specific unresolved factor");
});
it("rule: that factor must be capable of materially changing the preferred option", () => {
expect(prompt).toContain(
"could materially change which option is preferred",
);
});
it("rule: if no material factor remains, resolve existing decision context rather than asking generic question", () => {
expect(prompt).toContain(
"resolve the existing decision context",
);
expect(prompt).toContain(
"do not ask a generic continuation question",
);
});
it("does NOT introduce financial thresholds", () => {
expect(prompt).not.toContain("threshold");
expect(prompt).not.toContain("£600k");
expect(prompt).not.toContain("£2m");
expect(prompt).not.toContain("payback");
});
it("does NOT introduce relocation-specific examples", () => {
expect(prompt).not.toContain("relocation");
expect(prompt).not.toContain("Manchester");
expect(prompt).not.toContain("London");
expect(prompt).not.toContain("engineer");
});
it("does NOT introduce automatic resolution whenever one option appears better", () => {
// The rule must not say "always resolve" or "resolve when one looks better"
const sufficiencySection = prompt.split(
"## Decision Sufficiency Rule",
)[1].split("## Decision Option Structure Rules")[0];
expect(sufficiencySection).not.toContain("always resolve");
expect(sufficiencySection).not.toContain(
"resolve when one option",
);
expect(sufficiencySection).not.toContain("looks better");
});
it("does NOT introduce new schema fields or node kinds", () => {
// The rule text must not reference schema fields or node kinds outside the contract
expect(prompt).not.toContain("materiality_score");
expect(prompt).not.toContain("decision_sufficiency");
expect(prompt).not.toContain('kind "decision"');
});
it("does NOT mention specific currency or amounts", () => {
expect(prompt).not.toContain("£2 million");
expect(prompt).not.toContain("£600k");
expect(prompt).not.toContain("$1M");
expect(prompt).not.toContain("financial threshold");
});
it("existing Rule 20 preserved", () => {
expect(prompt).toContain(
"Return selectedQuestion as null only when no consequential unresolved unknown remains.",
);
});
it("is domain-general — no provider-specific, taxonomic, or keyword-based language", () => {
expect(prompt).not.toContain("qwen");
expect(prompt).not.toContain("claude");
expect(prompt).not.toContain("gpt");
expect(prompt).not.toContain("keyword");
expect(prompt).not.toContain("synonym");
});
it("preserves the possibility of keeping a decision open when grounded factor exists", () => {
// The rule must allow continuation when a specific unresolved factor could change the outcome
expect(prompt).toContain("specific unresolved factor");
expect(prompt).toContain("could materially change which option is preferred");
});
it("distinguishes uncertainty from decision-relevant uncertainty", () => {
// The rule must distinguish mere uncertainty from uncertainty that matters to the decision
const sufficiencySection = prompt.split(
"## Decision Sufficiency Rule",
)[1].split("## Decision Option Structure Rules")[0];
expect(sufficiencySection).toContain("should not remain open merely because some uncertainty still exists");
});
});