fix(confidence-engine): simplify active follow-up presentation
This commit is contained in:
@@ -274,7 +274,19 @@ function FocusedQuestionBody({
|
|||||||
<div><h3 className="mb-1 text-[11px] font-semibold tracking-widest uppercase text-gray-500">Questions this raises</h3>
|
<div><h3 className="mb-1 text-[11px] font-semibold tracking-widest uppercase text-gray-500">Questions this raises</h3>
|
||||||
{(focused.result.possibleFollowUpQuestions || []).length > 0 ? (
|
{(focused.result.possibleFollowUpQuestions || []).length > 0 ? (
|
||||||
<div className="space-y-1 mt-1">
|
<div className="space-y-1 mt-1">
|
||||||
{focused.result.possibleFollowUpQuestions.map((q, i) => {
|
{hasActiveFollowUp
|
||||||
|
? focused.result.possibleFollowUpQuestions.filter((q) => q !== focused.question).map((q, i) => (
|
||||||
|
<button
|
||||||
|
key={i}
|
||||||
|
onClick={(e) => { e.stopPropagation(); setFollowUpQuestion(q); }}
|
||||||
|
className="w-full text-left rounded-lg border border-blue-200/60 bg-blue-50/40 px-3 py-2.5 text-sm leading-relaxed text-gray-800 transition hover:border-blue-300 hover:bg-blue-100/60 cursor-pointer"
|
||||||
|
data-testid="follow-up-question"
|
||||||
|
>
|
||||||
|
{q}
|
||||||
|
{" → pick this question"}
|
||||||
|
</button>
|
||||||
|
))
|
||||||
|
: focused.result.possibleFollowUpQuestions.map((q, i) => {
|
||||||
const isCurrentQuestion = q === focused?.question;
|
const isCurrentQuestion = q === focused?.question;
|
||||||
return (
|
return (
|
||||||
<button
|
<button
|
||||||
|
|||||||
@@ -2158,3 +2158,39 @@ Those are distinct presentation responsibilities. Separating them exposes a dupl
|
|||||||
- Previous Learning single-owner presentation: CLOSED
|
- Previous Learning single-owner presentation: CLOSED
|
||||||
- Previous Learning newest-first: CLOSED
|
- Previous Learning newest-first: CLOSED
|
||||||
- Post-answer promotion: PRESERVED
|
- Post-answer promotion: PRESERVED
|
||||||
|
|
||||||
|
## v0.49 — ACTIVE FOLLOW-UP PRESENTATION SIMPLIFICATION
|
||||||
|
|
||||||
|
### Defect resolved
|
||||||
|
|
||||||
|
Selected follow-up candidate rendered twice inside "QUESTIONS THIS RAISES": once as a disabled `(current question)` row and again in the active continuation block above the textarea. Both rows contained the identical question text, creating visual redundancy.
|
||||||
|
|
||||||
|
### Fix summary
|
||||||
|
|
||||||
|
In `components/reasoning-workspace.jsx`, when `hasActiveFollowUp` is true (a follow-up has been selected), unselected candidates are still rendered with their existing selectable form (`→ pick this question`), but the candidate matching `focused.question` is filtered out from the candidate list entirely. The active continuation block already renders the selected question plus textarea + submit — no second rendering needed.
|
||||||
|
|
||||||
|
- Selected follow-up candidate now transforms into the active response block (single rendering).
|
||||||
|
- Duplicate `(current question)` / second-question rendering removed.
|
||||||
|
- Exactly one selected-question presentation.
|
||||||
|
- One textarea, Submit response visible.
|
||||||
|
- Completed Q/A provenance preserved.
|
||||||
|
- Previous Learning single-owner/newest-first preserved.
|
||||||
|
- Post-answer promotion preserved.
|
||||||
|
|
||||||
|
### Implementation detail
|
||||||
|
|
||||||
|
Production file changed: `components/reasoning-workspace.jsx` (candidate render boundary — lines ~275-300). No state added, no identity changes, no submit mechanics altered.
|
||||||
|
|
||||||
|
### Vitest config hygiene (from 8bded90)
|
||||||
|
|
||||||
|
vitest.config.js change classification: **A** — intentional and necessary (adds `environment: "jsdom"` required for React component testing in this repo).
|
||||||
|
|
||||||
|
### Tests
|
||||||
|
|
||||||
|
- Command: `npx vitest run tests/open-questions-vs-assumptions.test.jsx`
|
||||||
|
- Actual tests passed: **117** (up from 116 — one new regression test added)
|
||||||
|
- New regression assertion: verifies that after selecting a follow-up, the question text appears exactly once and no `(current question)` label is rendered.
|
||||||
|
|
||||||
|
### Build
|
||||||
|
|
||||||
|
- Result: PASS
|
||||||
|
|||||||
@@ -2195,5 +2195,59 @@ describe("v0.49 RENDERED — in-place follow-up context ownership", () => {
|
|||||||
const prevLearningHeadings = screen.queryAllByText(/previous learning/i);
|
const prevLearningHeadings = screen.queryAllByText(/previous learning/i);
|
||||||
expect(prevLearningHeadings).toHaveLength(1);
|
expect(prevLearningHeadings).toHaveLength(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// ── v0.49 REGRESSION: selected follow-up must not render twice ──
|
||||||
|
it("v0.49 regression: selected follow-up renders exactly once, no '(current question)' duplicate", () => {
|
||||||
|
const turn1Q = "Completed question?";
|
||||||
|
const turn1A = "Complete answer.";
|
||||||
|
|
||||||
|
// Q3 completed with raised follow-up Q4
|
||||||
|
const contribs = [
|
||||||
|
makeContrib(turn1Q, turn1A, 1),
|
||||||
|
];
|
||||||
|
|
||||||
|
// After setFollowUpQuestion: focused.question === "Q4", possibleFollowUpQuestions = ["Q4"], hasActiveFollowUp = true
|
||||||
|
render(
|
||||||
|
<div style={{ display: "grid", gridTemplateColumns: "1fr 1fr" }}>
|
||||||
|
<FocusedQuestionBody
|
||||||
|
nodeId="node-test"
|
||||||
|
isFocused={true}
|
||||||
|
hasContent={true}
|
||||||
|
processingStep="idle"
|
||||||
|
formulationStep="active"
|
||||||
|
deconstructMsg=""
|
||||||
|
focusedAnswer=""
|
||||||
|
setFocusedAnswer={() => {}}
|
||||||
|
handleDeconstructSubmit={() => {}}
|
||||||
|
retryFormulation={() => {}}
|
||||||
|
setFollowUpQuestion={() => {}}
|
||||||
|
focused={
|
||||||
|
{
|
||||||
|
question: "Q4",
|
||||||
|
answer: null,
|
||||||
|
status: "formulated",
|
||||||
|
result: {
|
||||||
|
observations: ["finding"],
|
||||||
|
uncertainties: [],
|
||||||
|
possibleFollowUpQuestions: ["Q4"],
|
||||||
|
assumptions: [],
|
||||||
|
relationships: [],
|
||||||
|
},
|
||||||
|
error: null,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
focusedContributions={contribs}
|
||||||
|
/>
|
||||||
|
</div>,
|
||||||
|
);
|
||||||
|
|
||||||
|
// The selected follow-up text should appear exactly once (in the active block), not duplicated in candidate row.
|
||||||
|
const q4Text = screen.getAllByText("Q4");
|
||||||
|
expect(q4Text).toHaveLength(1);
|
||||||
|
|
||||||
|
// After selection, "(current question)" label must NOT be rendered — the active form communicates selection unambiguously.
|
||||||
|
const currentQuestionLabels = screen.queryAllByText(/\(current question\)/i);
|
||||||
|
expect(currentQuestionLabels).toHaveLength(0);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
Reference in New Issue
Block a user