fix(confidence-engine): preserve completed-narrative when selecting follow-up + reverse prior-contribs display

Two presentation fixes (no reasoning-engine changes):

A. Follow-up answer continuity — selectFollowUpQuestion clears focused.answer,
   which previously caused the completed-narrative framing ('Previously answered'
   and 'Your response') to disappear mid-investigation. The guard now treats
   a non-null result as sufficient evidence of a completed-context state, so the
   user's verbatim answer and derived findings remain visible while a follow-up is
   being formulated.

B. Prior-contributions chronology — display order in 'Previous learning' panels
   has been reversed at the presentation boundary (newest → oldest). This means
   users see the most recently learned evidence first, without modifying data-order
   anywhere else. Applies to both PriorContributionsSummary and
   SecondaryPreviousLearning.
This commit is contained in:
2026-08-29 19:04:06 +01:00
parent 890a18c5a7
commit 17c6048047
2 changed files with 180 additions and 5 deletions
+14 -3
View File
@@ -145,6 +145,9 @@ function FocusedQuestionBody({
const hasContent = focused?.question?.trim() || formulationStep === "active" || processingStep === "active" || focused?.error;
const hasResult = Boolean(focused?.result);
const hasAnswer = Boolean(focused?.answer);
// A non-null result means we are still in a completed-context state even after the user selects a follow-up (which clears answer).
// Without this guard, selecting a follow-up question would erase "Previously answered" + "Your response".
const hasCompletedContext = processingStep !== "active" && Boolean(focused?.result);
// ── Local correction state (FQB-owned, not propagated upward) ─
const [editingFindingId, setEditingFindingId] = useState(null);
@@ -175,7 +178,7 @@ function FocusedQuestionBody({
{isFocused && hasContent && (
<div className="mt-4 space-y-4">
<div className="space-y-4 rounded-lg border border-gray-200 bg-white p-5">
{hasAnswer && focused?.question?.trim() ? (
{(hasAnswer || hasCompletedContext) && focused?.question?.trim() ? (
<div className="space-y-3">
{/* Previously answered question */}
<div>
@@ -511,12 +514,16 @@ function PriorContributionsSummary({ nodeId, contributions, findings }) {
const priorContribs = threadContribs.slice(0, -1);
if (!priorContribs.length) return null;
// Presentation-reversal: render newest prior turn first so user sees what was learned most recently at the top.
// This is a presentation-only decision; chronological order in data is preserved elsewhere.
const reversedPrior = [...priorContribs].reverse();
return (
<div className="rounded-lg border border-gray-200/60 bg-gray-50/40 px-4 py-3">
<h4 className="mb-1 text-[11px] font-semibold tracking-widest uppercase text-gray-500">
Previous learning
</h4>
{priorContribs.map((c, idx) => (
{reversedPrior.map((c, idx) => (
<details key={c.id || idx} className="mb-2 border-b border-gray-200/40 last:border-0 pb-2 last:pb-0" open={idx === 0}>
<summary className="cursor-pointer text-xs font-medium text-gray-500 hover:text-gray-700 select-none py-1">
Turn {c.sequence || idx + 1} contribution ({getHistoricalPropositions(c, findings).length ?? 0} observations, {c.uncertainties?.length ?? 0} unclear)
@@ -564,12 +571,16 @@ function SecondaryPreviousLearning({ nodeId, contributions, findings }) {
const priorContribs = threadContribs.slice(0, -1);
if (!priorContribs.length) return null;
// Presentation-reversal: render newest prior turn first so user sees what was learned most recently at the top.
// This is a presentation-only decision; chronological order in data is preserved elsewhere.
const reversedPrior = [...priorContribs].reverse();
return (
<div className="rounded-lg border border-gray-200/60 bg-gray-50/40 px-4 py-3">
<h4 className="mb-1 text-[11px] font-semibold tracking-widest uppercase text-gray-500">
Previous learning
</h4>
{priorContribs.map((c, idx) => (
{reversedPrior.map((c, idx) => (
<details key={c.id || idx} className="mb-2 border-b border-gray-200/40 last:border-0 pb-2 last:pb-0" open={idx === 0}>
<summary className="cursor-pointer text-xs font-medium text-gray-500 hover:text-gray-700 select-none py-1">
Turn {c.sequence || idx + 1} contribution ({getHistoricalPropositions(c, findings).length ?? 0} observations, {c.uncertainties?.length ?? 0} unclear)