test(ui): clarify branch provenance and hierarchy

This commit is contained in:
2026-08-20 06:15:44 +01:00
parent 0ac2e05c40
commit 8163c5d014
7 changed files with 49 additions and 33 deletions
+15 -7
View File
@@ -46,7 +46,7 @@ function NewIndicator({ visible }) {
/* ── Single branch row ─────────────────────────────────── */
function BranchRow({ id, label, active, isNew, onClick }) {
function BranchRow({ id, label, active, isNew, origin, onClick }) {
const isActive = Boolean(active);
return (
@@ -54,7 +54,7 @@ function BranchRow({ id, label, active, isNew, onClick }) {
onClick={onClick}
disabled={isActive}
aria-current={isActive ? "page" : undefined}
className={`w-full flex items-center gap-2 rounded-md px-3 py-2 text-left transition text-sm ${
className={`w-full flex items-start gap-2 rounded-md px-3 py-2 text-left transition text-sm ${
isActive
? "bg-blue-50/80 border border-blue-200/60 text-blue-900 font-medium"
: "text-gray-600 hover:bg-gray-100/70 hover:text-gray-800 border border-transparent"
@@ -70,8 +70,15 @@ function BranchRow({ id, label, active, isNew, onClick }) {
{isActive ? "●" : "○"}
</span>
{/* Branch label */}
<span className="flex-1 truncate">{label}</span>
{/* Branch label + origin */}
<span className="flex-1 min-w-0">
<span className="truncate block">{label}</span>
{origin && (
<span className="block text-[11px] leading-tight text-gray-500/80 truncate" title={origin}>
{origin}
</span>
)}
</span>
{/* Passive new-result indicator (only for inactive branches) */}
{!isActive && <NewIndicator visible={isNew} />}
@@ -96,11 +103,11 @@ export default function ExperimentalBranchSwitcher({
aria-label="Experimental branch switcher — RTO.25A"
>
{/* Label — clearly experimental */}
<h2 className="mb-1 text-[10px] font-semibold tracking-widest uppercase text-gray-400">
<h2 className="mb-1 text-[10px] font-semibold tracking-widest uppercase text-gray-600">
Branches{" "}
<span className="font-normal text-gray-300">(exp)</span>
<span className="font-normal text-gray-500">(exp)</span>
</h2>
<p className="mb-3 text-[11px] text-gray-400/60">
<p className="mb-3 text-[11px] font-medium leading-tight text-gray-500/80">
Browse branches. Current focus is preserved.
</p>
@@ -112,6 +119,7 @@ export default function ExperimentalBranchSwitcher({
label={branch.label}
active={activeBranchId === branch.id}
isNew={Boolean(branchNewResults[branch.id])}
origin={branch.origin}
onClick={() => onBranchSelect?.(branch.id)}
/>
))}
+2 -2
View File
@@ -84,10 +84,10 @@ export default function InvestigationMap({ turnCount = 0 }) {
return (
<div className="rounded-lg border border-gray-200/60 bg-gray-50/30 p-4" role="region" aria-label="Investigation map preview">
<h2 className="mb-1 text-[11px] font-medium tracking-widest uppercase text-gray-300">
<h2 className="mb-1 text-[11px] font-semibold tracking-widest uppercase text-gray-500">
Investigation Map
</h2>
<p className="mb-3 text-xs text-gray-400/70">
<p className="mb-3 text-xs font-medium leading-tight text-gray-500/80">
Active investigation topics and their status.
</p>
@@ -196,7 +196,7 @@ function InvestigationSummaryPanelV2({ graph, selectedQuestion, result, updateSt
<div>
{stillInvestigating.length > 1 ? (
<>
<h3 className="mb-2 text-xs font-medium text-gray-400">Still investigating</h3>
<h3 className="mb-2 text-xs font-medium text-gray-500">Still investigating</h3>
<ul className="space-y-1.5">
{Object.entries(investigatingByGroup).map(([group, items]) => (
<li key={group}>
@@ -227,7 +227,7 @@ function InvestigationSummaryPanelV2({ graph, selectedQuestion, result, updateSt
{/* ── What we have learned ────────────────────────── */}
{known.length > 0 && (
<div>
<h3 className="mb-2 text-xs font-medium text-gray-400">What we know</h3>
<h3 className="mb-2 text-xs font-medium text-gray-500">What we know</h3>
<ul className="space-y-1.5">
{known.map((item, i) => (
<li key={i} className="flex items-start gap-2">
@@ -243,8 +243,8 @@ function InvestigationSummaryPanelV2({ graph, selectedQuestion, result, updateSt
{/* ── Quiet reasoning summary — secondary ─────────── */}
<div className="pt-2 border-t border-gray-200/40">
<p className="text-[10px] font-medium tracking-widest uppercase text-gray-300 mb-1.5">Reasoning</p>
<div className="flex flex-wrap gap-x-4 gap-y-1 text-xs text-gray-400">
<p className="text-[10px] font-semibold tracking-widest uppercase text-gray-500 mb-1.5">Reasoning</p>
<div className="flex flex-wrap gap-x-4 gap-y-1 text-xs text-gray-500">
{reasonEntries.map(([label, count]) => (
<span key={label}>
{count} {label}
@@ -47,7 +47,7 @@ function KnownSection({ title, items }) {
return (
<div>
<h3 className="mb-2 text-[11px] font-medium tracking-widest uppercase text-gray-400">
<h3 className="mb-2 text-[11px] font-medium tracking-widest uppercase text-gray-500">
{title}
</h3>
<ul className="space-y-1.5">
@@ -67,7 +67,7 @@ function InvestigatingSection({ title, items }) {
return (
<div>
<h3 className="mb-2 text-[11px] font-medium tracking-widest uppercase text-gray-400">
<h3 className="mb-2 text-[11px] font-medium tracking-widest uppercase text-gray-500">
{title}
</h3>
<ul className="space-y-1.5">
@@ -87,7 +87,7 @@ function ExplanationSection({ items }) {
return (
<div>
<h3 className="mb-2 text-[11px] font-medium tracking-widest uppercase text-gray-400">
<h3 className="mb-2 text-[11px] font-medium tracking-widest uppercase text-gray-500">
Possible explanations
</h3>
<ul className="space-y-1.5">
@@ -102,10 +102,10 @@ function QuietSummary({ text }) {
return (
<div className="pt-2 border-t border-gray-200/40">
<p className="text-[10px] font-medium tracking-widest uppercase text-gray-300 mb-1.5">
<p className="text-[10px] font-semibold tracking-widest uppercase text-gray-500 mb-1.5">
Investigation state
</p>
<p className="text-xs text-gray-400">{text}</p>
<p className="text-xs text-gray-500">{text}</p>
</div>
);
}
+1 -1
View File
@@ -127,7 +127,7 @@ function InvestigationSummaryPanel({ graph, selectedQuestion, result, updateStat
{/* Current understanding */}
{currentUnderstanding && (
<div>
<h3 className="mb-1 text-[11px] font-medium tracking-widest uppercase text-gray-400/70">
<h3 className="mb-1 text-[11px] font-semibold tracking-widest uppercase text-gray-500">
What we understand so far
</h3>
<p className="text-sm leading-relaxed text-gray-600">{currentUnderstanding}</p>
+12 -12
View File
@@ -320,7 +320,7 @@ function CurrentUnderstandingCard({ currentSummary, plainLanguage }) {
return (
<div className="rounded-lg border border-gray-100/80 bg-transparent px-6 pt-5 pb-6">
<h2 className="mb-3 text-[11px] font-medium tracking-widest uppercase text-gray-300">
<h2 className="mb-3 text-[11px] font-semibold tracking-widest uppercase text-gray-500">
Understanding
</h2>
<p className="text-sm leading-relaxed text-gray-600">{summary}</p>
@@ -334,7 +334,7 @@ function PlainLanguageCard({ summary }) {
return (
<div className="rounded-lg border border-gray-100/80 bg-transparent px-6 pt-5 pb-6">
<h2 className="mb-3 text-[11px] font-medium tracking-widest uppercase text-gray-300">
<h2 className="mb-3 text-[11px] font-semibold tracking-widest uppercase text-gray-500">
Understanding
</h2>
<p className="text-sm leading-relaxed text-gray-600">{summary}</p>
@@ -382,7 +382,7 @@ function InvestigationHistory({ turns }) {
return (
<div className="space-y-3" data-testid="investigation-history">
<h2 className="text-[11px] font-medium tracking-widest uppercase text-gray-300">
<h2 className="text-[11px] font-semibold tracking-widest uppercase text-gray-500">
History
</h2>
<div className="space-y-2">
@@ -402,7 +402,7 @@ function OriginalSituation({ scenario, centralStatement }) {
return (
<div className="rounded-lg border border-gray-200/60 bg-gray-50/40 px-5 py-4">
<h2 className="mb-2 text-[11px] font-medium tracking-widest uppercase text-gray-300">
<h2 className="mb-2 text-[11px] font-semibold tracking-widest uppercase text-gray-500">
Situation
</h2>
@@ -832,7 +832,7 @@ export default function ReasoningWorkspace({
return (
<div className="space-y-4">
<h2 className="text-[11px] font-medium tracking-widest uppercase text-gray-300">
<h2 className="text-[11px] font-semibold tracking-widest uppercase text-gray-500">
In this branch Open questions
</h2>
<div className="space-y-1">
@@ -894,7 +894,7 @@ export default function ReasoningWorkspace({
{/* Formulated question */}
{focused?.question?.trim() ? (
<div>
<h3 className="mb-1 text-[11px] font-medium tracking-widest uppercase text-gray-300">
<h3 className="mb-1 text-[11px] font-semibold tracking-widest uppercase text-gray-500">
Question
</h3>
<p className="text-base font-medium leading-relaxed text-gray-900">
@@ -944,7 +944,7 @@ export default function ReasoningWorkspace({
{focused?.result && (
<>
<div>
<h3 className="mb-1 text-[11px] font-medium tracking-widest uppercase text-gray-300">
<h3 className="mb-1 text-[11px] font-semibold tracking-widest uppercase text-gray-500">
What we learned
</h3>
<ul className="list-disc pl-5 space-y-1">
@@ -955,7 +955,7 @@ export default function ReasoningWorkspace({
</div>
<div>
<h3 className="mb-1 text-[11px] font-medium tracking-widest uppercase text-gray-300">
<h3 className="mb-1 text-[11px] font-semibold tracking-widest uppercase text-gray-500">
Still unclear
</h3>
<ul className="list-disc pl-5 space-y-1">
@@ -967,7 +967,7 @@ export default function ReasoningWorkspace({
{focused.result.assumptions && focused.result.assumptions.length > 0 && (
<div>
<h3 className="mb-1 text-[11px] font-medium tracking-widest uppercase text-gray-300">
<h3 className="mb-1 text-[11px] font-semibold tracking-widest uppercase text-gray-500">
Assumptions in this response
</h3>
<ul className="list-disc pl-5 space-y-1">
@@ -980,7 +980,7 @@ export default function ReasoningWorkspace({
{focused.result.relationships && focused.result.relationships.length > 0 && (
<div>
<h3 className="mb-1 text-[11px] font-medium tracking-widest uppercase text-gray-300">
<h3 className="mb-1 text-[11px] font-semibold tracking-widest uppercase text-gray-500">
Connections
</h3>
<ul className="list-disc pl-5 space-y-1">
@@ -993,7 +993,7 @@ export default function ReasoningWorkspace({
{focused.result.possibleFollowUpQuestions && focused.result.possibleFollowUpQuestions.length > 0 && (
<div>
<h3 className="mb-1 text-[11px] font-medium tracking-widest uppercase text-gray-300">
<h3 className="mb-1 text-[11px] font-semibold tracking-widest uppercase text-gray-500">
Questions this raises
</h3>
<ul className="list-disc pl-5 space-y-1">
@@ -1059,7 +1059,7 @@ export default function ReasoningWorkspace({
{/* Done for now — separate visual area */}
{doneForNowIds.length > 0 && (
<div className="pt-3 border-t border-gray-200">
<h3 className="mb-2 text-[11px] font-medium tracking-widest uppercase text-gray-300">
<h3 className="mb-2 text-[11px] font-semibold tracking-widest uppercase text-gray-500">
Done for now
</h3>
<div className="space-y-1">
+10 -2
View File
@@ -225,8 +225,16 @@ export default function ScenarioForm() {
/* ── RTO.25A — passive late-result branch switcher (experimental) ── */
const BRANCHES = [
{ id: "branch-a", label: "Competitor development" },
{ id: "branch-b", label: "Customer demand" },
{
id: "branch-a",
label: "Competitor development",
origin: "Whether competitors are developing similar products and when they might release them",
},
{
id: "branch-b",
label: "Customer demand",
origin: "How many customers will buy the product, and what revenue that represents",
},
];
const [activeBranchId, setActiveBranchId] = useState("branch-b");