fix(confidence-engine): show focused investigation activity

This commit is contained in:
2026-08-29 16:46:51 +01:00
parent b9c0b6f6f7
commit dac19a3552
2 changed files with 30 additions and 81 deletions
+5 -81
View File
@@ -599,86 +599,10 @@ function ThreadContributionsBadge({ nodeId, contributions, findings }) {
);
if (!threadContribs.length) return null;
// Show most recent contribution summary inline
const latest = threadContribs[threadContribs.length - 1];
const nonEmptyGroups = [];
for (const key of ["observations", "uncertainties", "assumptions", "relationships"]) {
const arr = latest[key];
if (Array.isArray(arr) && arr.length > 0) nonEmptyGroups.push(key);
}
return (
<div className="mt-3">
{/* Thread activity cue: visible when this node has focused investigation history */}
<span className="mb-1 block text-[9px] uppercase tracking-widest font-semibold text-amber-500/70">
INVESTIGATING
</span>
{/* Thread learning indicator — collapsed by default; user can expand to inspect history */}
<details open={false} className="rounded-lg border border-gray-200/80 bg-white/60">
<summary className="cursor-pointer px-3 py-1.5 text-xs font-medium text-gray-600 hover:text-gray-800 select-none">
📝 {threadContribs.length} learned contribution{threadContribs.length !== 1 ? "s" : ""}
</summary>
<div className="px-3 pb-3 pt-1 space-y-4">
{/* All contributions listed in order */}
{threadContribs.map((c, idx) => (
<div key={c.id || idx} className="space-y-2">
{idx > 0 && <div className="text-[9px] text-gray-400 tracking-wider uppercase mt-3">Contribution #{c.sequence || idx + 1}</div>}
{/* What this tells us — via canonical Findings */}
{(() => {
const propositions = getHistoricalPropositions(c, findings);
return propositions.length ? (
<div>
<h4 className="text-[10px] font-semibold tracking-widest uppercase text-gray-500">What this tells us</h4>
<ul className="list-disc pl-5 space-y-0.5">
{propositions.map((o, i) => (
<li key={i} className="text-xs leading-relaxed text-gray-700">{o}</li>
))}
</ul>
</div>
) : null;
})()}
{/* Still unclear */}
{c.uncertainties?.length ? (
<div>
<h4 className="text-[10px] font-semibold tracking-widest uppercase text-gray-500">Still unclear</h4>
<ul className="list-disc pl-5 space-y-0.5">
{c.uncertainties.map((u, i) => (
<li key={i} className="text-xs leading-relaxed text-gray-700">{u}</li>
))}
</ul>
</div>
) : null}
{/* Assumptions */}
{c.assumptions?.length ? (
<div>
<h4 className="text-[10px] font-semibold tracking-widest uppercase text-gray-500">Assumptions</h4>
<ul className="list-disc pl-5 space-y-0.5">
{c.assumptions.map((a, i) => (
<li key={i} className="text-xs leading-relaxed text-gray-700">{a}</li>
))}
</ul>
</div>
) : null}
{/* Connections */}
{c.relationships?.length ? (
<div>
<h4 className="text-[10px] font-semibold tracking-widest uppercase text-gray-500">Connections</h4>
<ul className="list-disc pl-5 space-y-0.5">
{c.relationships.map((r, i) => (
<li key={i} className="text-xs leading-relaxed text-gray-700">{r.from} {r.to} ({r.type})</li>
))}
</ul>
</div>
) : null}
</div>
))}
</div>
</details>
</div>
<span className="mt-2 block text-[9px] uppercase tracking-widest font-semibold text-amber-500/70">
INVESTIGATING · {threadContribs.length} learned contribution{threadContribs.length !== 1 ? "s" : ""}
</span>
);
}
@@ -1233,7 +1157,7 @@ function OpenQuestionsPanel({
onUpdateFindingProposition={onUpdateFindingProposition}
/>
{/* Thread contributions for this node */}
{/* Thread contributions for this node — compact cue inside card */}
<ThreadContributionsBadge nodeId={node.id} contributions={focusedContributions || []} findings={findings} />
</div>
</div>
@@ -1832,8 +1756,8 @@ export default function ReasoningWorkspace({
<p className="mt-1.5 text-xs leading-snug text-gray-500">{node.description}</p>
)}
{!isFocused && <span className="mt-2 block text-[10px] uppercase tracking-wider text-gray-400">Unclear</span>}
<ThreadContributionsBadge nodeId={node.id} contributions={focusedContributions || []} findings={findings} />
</button>
<ThreadContributionsBadge nodeId={node.id} contributions={focusedContributions || []} findings={findings} />
</div>
);
})}
+25
View File
@@ -1946,3 +1946,28 @@ Target node: `n58lwnx`
- do not create a fresh scenario unless an experiment explicitly requires one;
- if this investigation is absent, report TEST-STATE MISSING rather than diagnosing persistence failure;
- structural/relative assertions only for LLM output — no exact prose dependency.
## v0.49.6 — OPEN QUESTION ACTIVITY VISIBILITY — VERIFIED
- **Status:** CLOSED / CHECKPOINTED
- `INVESTIGATING` is an activity/history cue independent from epistemic `Unclear`
- overview presentation is compact and non-expandable: `INVESTIGATING · N learned contribution(s)`
- cue lives inside the originating Open Question card
- activity derives from canonical focused Contributions using: `targetNodeId OR originatingTargetNodeId`
- investigated card was live verified after return from workspace
- untouched question remained without activity cue
- cue survived cold reload
- Open Question card remains the route into detailed investigation history
- zero LLM calls during verification
- targeted tests: 89 PASS
- build: PASS
### Unresolved boundaries (no diagnosis)
- completed-turn vs active-turn reconstruction
- empty response textarea against an already-completed historical question
- `Back to open questions` lifecycle
- top-right `Close investigation` wording / likely `Close workspace`
- `Done for now` remains a separate semantic action
**Next boundary:** FOCUSED WORKSPACE COMPLETED-TURN / ACTIVE-TURN LIFECYCLE