Files
confidence-engine/docs/experiment-60b73.md
T

113 lines
4.6 KiB
Markdown

# Experiment 60B.73 — Missing Sufficiency Confirmation Question (Implementation)
**Date:** 2026-08-14
**Branch:** `feature/sufficiency-confirmation-question-v0.45`
**Parent:** 60B.72 (diagnosis ready for implementation)
**Type:** Bounded implementation + focused verification
## Objective
Replace the generic decision_threshold question ("What outcome would demonstrate enough value to justify X?") with a focused sufficiency confirmation/discovery question when:
```text
target is an unresolved decision
AND hasRemainingMaterialFactors(target.id, graph) === false
AND isUserConfirmationOfNoRemainingUncertainty(raw answer) === false
```
## Implementation Boundary
Location: `formulateQuestion()` in `lib/graph/question-formulator.js`
Branch: Before `selectInvestigationStrategy()` call
Detection: Transient (no persisted state)
### Detection Logic
State B detected in `formulateQuestion` after `reasoningPatternSelection` and before strategy selection:
```js
// Guarded to decision-pattern context only
if (
reasoningPatternSelection.pattern === "decision" &&
node.kind !== "unknown" && // not a factor — the target decision itself
node.status !== "known" && // still unresolved
node.status !== "resolved" &&
node.status !== "contradicted" &&
hasRemainingMaterialFactors(node.id, graph) === false
) {
const resolved = context.resolvedValues || [];
const hasConfirmation = resolved.some((v) =>
isUserConfirmationOfNoRemainingUncertainty(v),
);
if (!hasConfirmation) sufficiency template
}
```
## New Template
Key: `decision_threshold_sufficiency_confirmation`
Family: `decision_threshold` (existing family, no new family)
Question: "Is there anything else material that could change which option is better?"
This question preserves both functions:
1. User can answer "No" to confirm sufficiency → closure proceeds
2. User can name another factor if one exists → that factor becomes next unknown
## Test Coverage (60B.73 — 8 tests)
| # | Scenario | Expected |
|---|----------|----------|
| 1 | Exact State B: unresolved decision, zero remaining factors, no confirmation | sufficiency template selected; generic threshold wording absent |
| 2 | Question allows missing-factor discovery | Contains "anything else material" and "could change which option is better" |
| 3 | Genuine remaining factor remains | Normal path preserved; NOT sufficiency template |
| 4 | Explicit sufficiency confirmation present | Normal path preserved; NOT sufficiency template |
| 5 | Non-decision unknown target | Unchanged normal behavior |
| 6 | Ordinary decision_threshold for unknown factors | `decision_threshold` family preserved |
| 7 | Resolved factor stays resolved (zero remaining) | State B triggers correctly |
| 8 | Decision identity preserved | Reason mentions material factors; node unchanged |
## Behavioral Guardrails
### Preserved (NOT changed):
- Target selection logic
- Decision closure rule (`shouldCloseDecision` in decision-sufficiency.js)
- Remaining-factor detection (`hasRemainingMaterialFactors`)
- Resolution semantics
- SelectedQuestion node identity
- Materiality determination
- Preferred option / recommendation
- Schema / provider / harness
- Existing factor-first question behavior
### Not changed:
```text
new schema field → NO
new persisted graph state → NO
new question family → NO (uses existing decision_threshold)
prompt change → NO
broad answer plumbing → NO (uses existing resolvedValues context)
```
## Focused Verification
Command: `npx vitest run tests/graph/question-formulator.test.js tests/graph/apply-proposal.test.js -t "60B.73|60B.64|decision_threshold"`
Result: 16 passed (8 new + 8 regression/preserved)
## Pre-existing Regressions (NOT introduced by this experiment)
Four apply-proposal test failures confirmed pre-existing (verified via git stash/re-run):
1. "rejects selected question referencing resolved node" — validation not catching resolved ref
2-4. Question casing mismatch: expects lowercase, receives capitalized
## WHAT IS NOW GUARANTEED
When the active target is an unresolved decision with zero represented remaining material factors but no explicit sufficiency confirmation:
- Engine asks focused sufficiency confirmation/discovery question instead of generic threshold question
- Decision remains the active target (no target change)
- The question allows both "No" (confirm sufficiency) and factor discovery
## WHAT REMAINS UNPROVEN
The 60B.71 live no-confirmation case must still be rerun once after this implementation to prove the user-facing question changes from generic decision_threshold to focused sufficiency confirmation/discovery.