feat(confidence-engine): place zero-Open-Questions milestone at Open Questions position
Move the milestone invitation from after Clarified Questions to occupy the same spatial position as Open Questions — between Current Understanding and Questions we have clarified. Uses ternary: openUnknowns > 0 ? OpenQuestionsUI : milestoneAllowed ? MilestoneInvitation : null, followed by ClarifiedQuestionsUI unconditionally. No duplication of clarified cards or Re-open controls.
This commit is contained in:
@@ -232,3 +232,52 @@ Finding↔SituationGraph reasoning contract → captured in authoritative graph
|
||||
```
|
||||
|
||||
These architectural decisions are preserved as settled current state, not as historical narrative. Detailed experiment evidence remains in `docs/archive/experiments/`.
|
||||
|
||||
### Open Questions filtering surfaces (durable production fact)
|
||||
|
||||
Two separate surfaces render Open Questions from the same graph data but use different filter rules:
|
||||
|
||||
- **Inline Open Questions** (`ReasoningWorkspace`, line ~1841): filters by `n.kind === "unknown" && !resolvedIds.has(n.id)` — uses `resolvedNodeIds` **only**.
|
||||
- **OpenQuestionsPanel** (same file, line ~1193): filters by `n.kind === "unknown" && !resolvedIds.has(n.id) && !doneForNowIds.includes(n.id)` — uses **both** `resolvedNodeIds` and `doneForNowIds`.
|
||||
|
||||
**Immediate Done behavior:** Both surfaces remove the question simultaneously (React batches both `onImmediateGraphChange` → `setResult` and `setDoneForNowIds` in the same render cycle, so both see the updated state on the next paint).
|
||||
|
||||
**Post-server-confirmation inconsistency (open): conditional structural risk.** If the server returns a graph that does **not** include the node in `resolvedNodeIds`, OpenQuestionsPanel (pre-v0.51) still hides it (because `doneForNowIds` persisted), but the inline surface shows it as open again.
|
||||
|
||||
---
|
||||
|
||||
### Zero Open Questions invitation — v0.51 correction (verified)
|
||||
|
||||
**Live evidence that motivated this correction:**
|
||||
|
||||
A real completed investigation reached zero Open Questions, clarified questions were visible, CU refreshed correctly, but the invitation was absent because its prerequisite was tied to transient `doneForNowIds` rather than canonical graph state.
|
||||
|
||||
**Correction applied — eligibility:** Invitation uses canonical resolved-node graph state (same derivation as inline "Questions we have clarified"), not local `doneForNowIds`:
|
||||
|
||||
- `openUnknowns.length === 0 AND clarifiedQuestions.length > 0 AND !cuSynthesisLoading`
|
||||
- Clarification count = unknown nodes in `resolvedNodeIds` (same source as inline section)
|
||||
- Re-open behavior preserved (still uses `setDoneForNowIds` for local toggle)
|
||||
- "Review current understanding" reveals existing CU via `cu-scroll-target` without triggering synthesis or new LLM call
|
||||
- Invitation hidden while `cuSynthesisLoading === true`; appears after CU refresh completes
|
||||
- Zero Open Questions carries no readiness/completion judgement — it is a milestone invitation, not a decision
|
||||
|
||||
**Exact working copy:** "You've now worked through all of the questions we surfaced. Would you like to see an overview of what we understand so far?"
|
||||
|
||||
**Action:** "Review current understanding" (scrolls to CU section)
|
||||
|
||||
**Placement correction (v0.51 placement):**
|
||||
- The milestone invitation occupies the same conceptual/spatial position previously occupied by Open Questions — between Current Understanding and Questions we have clarified.
|
||||
- When Open Questions still exist: Current Understanding → Open Questions → Questions we have clarified
|
||||
- When zero Open Questions: Current Understanding → Milestone invitation → Questions we have clarified
|
||||
- This is a ternary in the inline ReasoningWorkspace section: `openUnknowns.length > 0 ? <OpenQuestionsUI> : milestoneAllowed ? <MilestoneInvitation> : null`, followed by `<ClarifiedQuestionsUI />` unconditionally.
|
||||
|
||||
**Verification:**
|
||||
- Rob manually verified the milestone renders correctly on persisted investigation at `http://localhost:3000` (before placement correction)
|
||||
- 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
|
||||
- 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.
|
||||
|
||||
Reference in New Issue
Block a user