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
+8
View File
@@ -134,6 +134,14 @@ The JSON object must contain exactly these top-level fields:
31. If the answer explicitly states a hard constraint, state that directly in userSupportedMeaning.
32. Populate resolutionGuidance when the user's meaning genuinely implies must_remain_unresolved, may_resolve, or must_resolve. Keep it null only when no existing resolution state actually applies.
## Decision Sufficiency Rule
An unresolved decision between options should not remain open merely because some uncertainty still exists.
Keep a decision context unresolved only when you can identify a specific unresolved factor that could materially change which option is preferred.
If the currently supported evidence is sufficient to distinguish the options and no such material unresolved factor remains, resolve the existing decision context and do not ask a generic continuation question.
## Decision Option Structure Rules
When the user presents mutually exclusive candidate actions for one unresolved choice:
+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");
});
});