feat(confidence-engine): clarify understanding during Done refresh

This commit is contained in:
2026-09-02 07:53:45 +01:00
parent b647236d44
commit 043ba5f264
5 changed files with 207 additions and 13 deletions
+32 -5
View File
@@ -394,7 +394,7 @@ function FocusedQuestionBody({
// ── Persistent navigation controls (overlay-level, outside content grid) ──
function FocusedWorkspaceNavigation({ nodeId, doneForNow, isDoneForNowActive, isProcessing }) {
function FocusedWorkspaceNavigation({ nodeId, doneForNow, isDoneForNowActive, isProcessing, onImmediateGraphChange }) {
const canDoneForNow = Boolean(isDoneForNowActive) && !isProcessing;
return (
<div className="mt-6 flex items-center justify-end border-t border-gray-200 pt-5">
@@ -1303,6 +1303,7 @@ export default function ReasoningWorkspace({
scenario,
status,
updateStatus,
cuSynthesisLoading,
currentUnderstanding: propUnderstanding,
result,
answer,
@@ -1317,8 +1318,12 @@ export default function ReasoningWorkspace({
onUpdateFindingProposition,
/* ── v0.49 — done-for-now promotion callback ───────── */
onSummaryUpdate,
/* ── immediate graph transition (Done acknowledged before async) ── */
onImmediateGraphChange,
/* ── canonical graph-replacement seam (future Re-open) ── */
onSituationGraphChange,
/* ── test init seam (no effect → immediate state) ───────── */
initialPostAnalyseStatus,
}) {
const [investigationHistory, setInvestigationHistory] = useState([]);
const turnCounter = useRef(0);
@@ -1338,7 +1343,7 @@ export default function ReasoningWorkspace({
// ── RTO.29D — post-Analyse initial reflection surface ─────────
const [initialReflectionActive, setInitialReflectionActive] = useState(false);
const [postAnalyseStatus, setPostAnalyseStatus] = useState(null);
const [postAnalyseStatus, setPostAnalyseStatus] = useState(initialPostAnalyseStatus ?? null);
// Capture the current selected question at submit time (not from a stale ref)
const capturePendingTurn = (selectedQuestion, answerText) => {
@@ -1790,11 +1795,21 @@ export default function ReasoningWorkspace({
{/* Current Understanding + Situation — independent vertical flow */}
<div className="flex gap-3 items-start flex-wrap">
{/* Current Understanding — prominent orienting surface */}
<div className={`rounded-xl border-[2.5px] border-teal-300/70 bg-gradient-to-b from-teal-50/60 to-white px-8 pt-7 pb-8 shadow-sm flex-1 min-w-0 ${hasGraph ? 'lg:max-w-2xl' : ''}`}>
<div className={`rounded-xl border-[2.5px] border-teal-300/70 bg-gradient-to-b from-teal-50/60 to-white px-8 pt-7 pb-8 shadow-sm flex-1 min-w-0 relative ${hasGraph ? 'lg:max-w-2xl' : ''}`}>
<h2 className="mb-4 text-[11px] font-bold tracking-[.18em] uppercase text-teal-700/60">
Current Understanding
</h2>
<p className="text-lg leading-relaxed text-gray-800">{propUnderstanding}</p>
{cuSynthesisLoading && (
<div className="absolute inset-0 cu-skeleton-overlay rounded-xl overflow-hidden flex flex-col items-center justify-center bg-gray-50" role="status" aria-live="polite">
<p className="text-sm font-semibold text-teal-800 mb-6 relative z-10 tracking-wide">Clarifying your current understanding</p>
<div className="cu-skeleton-lines w-full max-w-lg px-8 pb-8" aria-hidden="true">
{Array.from({ length: 7 }, (_, i) => (
<div key={i} className={`cu-skeleton-line mb-3 ${['w-[94%]', 'w-[87%]', 'w-[96%]', 'w-[72%]', 'w-[90%]', 'w-[82%]', 'w-[64%]'][i % 7]}`} />
))}
</div>
</div>
)}
</div>
{/* Situation panel during initial reflection */}
@@ -1990,7 +2005,7 @@ export default function ReasoningWorkspace({
{/* Current Understanding — independent row, full-width of left area (cols 1-2) */}
{propUnderstanding && hasCurrentSummaryCondition && postAnalyseStatus !== "success" && (
<div className="lg:row-start-1 lg:col-span-full rounded-xl border-[2.5px] border-teal-300/70 bg-gradient-to-b from-teal-50/60 to-white px-8 pt-7 pb-8 shadow-sm">
<div className="lg:row-start-1 lg:col-span-full rounded-xl border-[2.5px] border-teal-300/70 bg-gradient-to-b from-teal-50/60 to-white px-8 pt-7 pb-8 shadow-sm relative">
<CurrentUnderstandingCard currentSummary={graph?.currentSummary || result?.updatedSituationGraph?.currentSummary} plainLanguage={propUnderstanding} />
</div>
)}
@@ -2211,7 +2226,18 @@ export default function ReasoningWorkspace({
nodeId={focusedPresentationItemId}
doneForNow={() => {
if (processingStep === "active") return;
/* ── v0.49 — promote eligible focused findings into Current Understanding ─── */
/* ── Immediate transition: resolve target node BEFORE async — cuSynthesisLoading also set ─── */
if (onImmediateGraphChange && focusedPresentationItemId) {
const currentGraph = result?.situationGraph;
if (currentGraph) {
const resolvedIds = new Set(currentGraph.resolvedNodeIds || []);
resolvedIds.add(focusedPresentationItemId);
onImmediateGraphChange({
...currentGraph,
resolvedNodeIds: Array.from(resolvedIds),
});
}
}
onSummaryUpdate?.(focusedPresentationItemId);
setDoneForNowIds((prev) => [...prev, focusedPresentationItemId]);
setFocusedAnswer("");
@@ -2221,6 +2247,7 @@ export default function ReasoningWorkspace({
}}
isDoneForNowActive={Boolean(getFocusedInvestigation()?.question?.trim())}
isProcessing={processingStep === "active"}
onImmediateGraphChange={onImmediateGraphChange}
/>
)}
</>