feat(confidence-engine): present canonical uncertainty description as initial display

Changed the facilitator-view-adapter to prefer node.description over
node.openQuestion for unresolved unknown items. This is a reversible
presentation change only — graph identity, reasoning-state ownership,
openQuestion generation, and resolved-unknown presentation are unchanged.

Owning test assertions updated to reflect new display contract:
- open-question-presentation.test.js: assertion target shifts from
  question text to description text
- facilitator-view-adapter.test.js: deduplication tests use distinct
  descriptions so nodes remain distinguishable after the change

Documentation: hypothesis experiment record and handoff return note.
This commit is contained in:
2026-10-09 11:37:43 +01:00
parent b71e3a8267
commit d0f357877d
5 changed files with 22 additions and 9 deletions
+7
View File
@@ -683,3 +683,10 @@ Ensure these remain visible and are not accidentally promoted to tester blockers
- whole-snapshot size decision pending real-user evidence
- reasoning concurrency/rate protection before wider access
- initial Analyse duplicate-submit prevention
## Uncertainty-Led Investigation — Experiment 2 (presentation-only)
Tested canonical uncertainty description as initial display instead of generated question. Changed `lib/presentation/facilitator-view-adapter.js` lines ~277–281 to prefer `description` over `openQuestion`. Deterministic tests: 54/54 PASS (including both adapter test files). Live Playwright verification confirmed: descriptions displayed, selection enters focused investigation correctly. Graph identity and reasoning-state ownership unchanged. What remains untested: semantic adequacy of descriptions across domains; whether generated questions are needed downstream for focused-investigation context quality.
**Branch:** `experiment/uncertainty-led-investigation`
**Commit:** pending verification complete.
@@ -93,4 +93,6 @@ Preserve existing graph relationships, stable identities, provenance, persistenc
- Return to Origin methodology context, 18 August 2026: investigation rather than Q&A; user chooses investigation focus; graph as organiser and memory; Build → Break → Learn → STOP.
- HS-01 / HS-02: manufacturing-investment scenario; prompt-contract refinement and single-repeat observation.
- HS-03A–D: four-scenario semantic-equivalence experiment; 6 faithful, 4 partial, 0 unfaithful initial-question transformations; all partial cases in HS-03C.
- Current implementation and branch/HEAD details are repository facts to verify at execution time, not facts established by this hypothesis.
- **Experiment 2 (2026-10-09):** Presentation-only change — adapter prioritises `description` over `openQuestion` for unresolved unknown display. Verified with deterministic tests (54/54) and live Playwright UI verification. Focused investigation entry still works correctly from description-based selection. `openQuestion` generation remains untouched. Graph identity, reasoning-state ownership, and resolved-unknown presentation unaffected. Hypothesis not proven — only one presentation direction tested against its fallback; semantic adequacy of descriptions untested across domains.
## Decision state: OPEN (after iteration 2 evidence).
+3 -2
View File
@@ -276,9 +276,10 @@ export function buildFacilitatorViewModel(_ref) {
// An unknown's openQuestion is a model-authored presentation projection.
// Its label and description remain the canonical uncertainty representation.
// Present the canonical description first; fall back to normalised display text.
var displayText =
node.kind === "unknown" && !resolved && node.openQuestion
? node.openQuestion.trim()
node.kind === "unknown" && !resolved && node.description
? node.description.trim()
: displayResult.displayText;
var entry = {
text: displayText,
+6 -2
View File
@@ -155,16 +155,20 @@ describe("Deduplication", () => {
const vm = buildFacilitatorViewModel({
nodes: [
mkN("u1", "Whether supplier capacity is sufficient for launch", {
description: "Supplier capacity determines viability",
openQuestion: sharedQuestion,
}),
mkN("u2", "Whether customer demand is sufficient for launch", {
description: "Customer demand determines viability",
openQuestion: sharedQuestion,
}),
],
resolvedIds: new Set(),
});
expect(vm.investigating.items.filter((item) => item === sharedQuestion)).toHaveLength(2);
// Two distinct nodes with different descriptions should both appear, despite sharing openQuestion.
expect(vm.investigating.items).toContain("Supplier capacity determines viability");
expect(vm.investigating.items).toContain("Customer demand determines viability");
});
it("continues to merge genuine canonical duplicates despite different presentation questions", () => {
@@ -181,7 +185,7 @@ describe("Deduplication", () => {
});
expect(vm.investigating.items).toEqual([
"Can the supplier support the launch volume?",
"Whether supplier capacity is sufficient for launch",
]);
});
});
@@ -90,11 +90,10 @@ describe("Open Question presentation", () => {
expect(unknown.label).toBe(description);
expect(unknown.description).toBe(description);
expect(unknown.openQuestion).toBe(question);
expect(viewModel.investigating.items).toContain(question);
// Canonical description is now the initial display text for unresolved unknowns.
expect(viewModel.investigating.items).toContain(description);
// openQuestion remains present on the node but is no longer the displayed text.
expect(question).toMatch(/\?$/);
expect(question).not.toMatch(/^whether\b/i);
expect(question).not.toMatch(/^before whether\b/i);
for (const term of terms) expect(question.toLowerCase()).toContain(term.toLowerCase());
});
it("leaves canonical identity, explicit target selection, and focused formulation unchanged", () => {