fix(confidence-engine): scope focused presentation to active question

- FocusedQuestionBody derives thread-local contribution subset using
  targetNodeId || originatingTargetNodeId matching
- hasCompletedContext, latest completed contrib, and all effective
  presentation fallbacks use scoped collection only
- scenario-wide focusedContributions history preserved in memory
- Fresh Question B no longer bleeds Question A's content across
  every presentation surface (Previously answered, What this tells us,
  Still unclear, Questions this raises, Assumptions, Connections)
- Reopening or revisiting Question A still uses its own history
- Targeted regression: 3 new Vitest cases pass
- Handoff docs updated with v0.52 correction record
This commit is contained in:
2026-09-02 12:46:50 +01:00
parent a061428711
commit 2b2096e41d
3 changed files with 181 additions and 5 deletions
+41 -3
View File
@@ -276,8 +276,46 @@ A real completed investigation reached zero Open Questions, clarified questions
- This session corrected placement via Edit only; deterministic verification via targeted Vitest (145 tests) and build — deliberately did not repeat Playwright
- All 145 tests pass; production build compiles successfully
**Open defects (unchanged):**
- Focused-investigation state bleed: newly selected Open Question can show stale previous-question material — separate future increment
### Focused investigation presentation ownership — v0.52 correction (verified)
**Live evidence that motivated this correction:**
A fresh unanswered Question B displayed stale focused-investigation content from a previously answered Question A across every presentation surface:
- Previously answered / Your response
- What this tells us
- Still unclear
- Questions this raises
- Assumptions
- Connections
**Root cause:** `FocusedQuestionBody` in `components/reasoning-workspace.jsx` iterated over the scenario-wide `focusedContributions` array for all derivations (`hasCompletedContext`, latest completed contribution, and every effective-presentation fallback: observations, uncertainties, follow-ups, assumptions, relationships). No active-question scoping was applied.
**Correction applied — scoped contribution presentation:**
- `FocusedQuestionBody` now derives a thread-local subset before any derivation:
```js
const threadContribs = (focusedContributions || []).filter(
(c) => c.targetNodeId === nodeId || c.originatingTargetNodeId === nodeId,
);
```
- `hasCompletedContext`, latest completed contribution, and all effective presentation fallbacks use that scoped collection;
- scenario-wide `focusedContributions` history is preserved in memory — only the presentation derivation is narrowed;
- `originatingTargetNodeId` is also checked so follow-up contributions remain attributed to their originating question;
- fresh Question B no longer inherits Question A's focused presentation content;
- reopening or revisiting Question A still correctly uses Question A's own historical contribution content.
**Verified:**
- targeted Vitest (`tests/open-questions-vs-assumptions.test.jsx`) — 3 new test cases (fresh B scoped to zero, active A retains its history, originatingTargetNodeId scoping) — pass
- `npm run build` — compiles successfully
- Rob manually verified the live UI on a persisted investigation: fresh unanswered Question B no longer shows stale focused-investigation content from Question B; confirmed across all six presentation surfaces listed above
**Verification notes:**
- Claude Playwright was not used for final verification because the canonical dev server was unavailable at that point
- Full Vitest suite was not re-run in this session (only targeted regression test)
### Open defects
- **Focused-investigation state bleed**: Resolved by v0.52 correction above (scoped presentation derivation). Verified by targeted Vitest, build, and Rob manual visual verification.
- Empty Done `no_episodic_content`: choosing Done without episodic content can produce `{ success: false, stage: "preparation", error: "no_episodic_content" }` — separate future increment
**Next restart point:** Place milestone at Open Questions position when reverting placement correction. See v0.51 placement section above for the exact ternary pattern.
**Next restart point:** The empty-Done `no_episodic_content` 400. Implement and verify that a Done action taken when no episodic evidence exists produces the same user-facing state (CU refresh with appropriate messaging) without a 400 error.