test(ui): isolate branch scoped workspace experiment
This commit is contained in:
@@ -522,6 +522,11 @@ export default function ReasoningWorkspace({
|
||||
lastSubmittedAnswer,
|
||||
onRestart,
|
||||
branchContext,
|
||||
// ── RTO.26B — branch-local reasoning (explicit provenance) ──
|
||||
experimentalBranches,
|
||||
branchLocalQuestions,
|
||||
branchLocalContributions,
|
||||
inactiveBranchNewResults,
|
||||
}) {
|
||||
const [investigationHistory, setInvestigationHistory] = useState([]);
|
||||
const turnCounter = useRef(0);
|
||||
@@ -811,7 +816,7 @@ export default function ReasoningWorkspace({
|
||||
)}
|
||||
|
||||
{/* ── No graph produced after initial analysis ───────── */}
|
||||
{(status === "success" || status === "error") && !graph ? (
|
||||
{(status === "success" || status === "error") && !graph && !(experimentalBranches && experimentalBranches.length > 0) ? (
|
||||
<div className="rounded-lg border border-yellow-300 bg-yellow-50 px-4 py-3 text-sm text-yellow-800">
|
||||
{diagnostics?.noQuestionReason
|
||||
? "Validation failed — no structured graph output was produced."
|
||||
@@ -820,12 +825,21 @@ export default function ReasoningWorkspace({
|
||||
) : (
|
||||
<>
|
||||
{/* ── Workspace grid: persistent whenever a graph exists ─── */}
|
||||
{hasGraph && (
|
||||
{(hasGraph || experimentalBranches) && (
|
||||
<div className="grid grid-cols-1 gap-6 lg:grid-cols-3">
|
||||
{/* ── Left lane: active conversation & notebook ───────── */}
|
||||
<div className="space-y-6 lg:col-span-2">
|
||||
<div className={`space-y-6 ${hasGraph ? 'lg:col-span-2' : 'lg:col-span-full'}`}>
|
||||
{/* RTO.26B — experiment header when using branch-scoped fixture */}
|
||||
{experimentalBranches && experimentalBranches.length > 0 && (
|
||||
<div className="rounded-lg border border-purple-300/60 bg-purple-50/30 px-4 py-2">
|
||||
<p className="text-[10px] font-semibold tracking-widest uppercase text-purple-400/70">
|
||||
RTO.26B — branch-scoped reasoning (experimental fixture)
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Active branch context (experiment RTO.25D) */}
|
||||
{branchContext && hasGraph && (
|
||||
{branchContext && (hasGraph || experimentalBranches) && (
|
||||
<div className="rounded-lg border border-blue-200/60 bg-blue-50/40 px-5 py-4">
|
||||
<h2 className="mb-1 text-[11px] font-semibold tracking-widest uppercase text-gray-500">
|
||||
Current branch
|
||||
@@ -841,9 +855,12 @@ export default function ReasoningWorkspace({
|
||||
|
||||
{/* ── Open questions (case workspace) — no ranking bias ── */}
|
||||
{(() => {
|
||||
const openNodes = graph.nodes.filter(
|
||||
(n) => n.kind === "unknown" && n.status !== "resolved" && !doneForNowIds.includes(n.id)
|
||||
);
|
||||
/* RTO.26B: when experimental branch-scoped data is present, use it as the source of truth */
|
||||
const openNodes = experimentalBranches && branchLocalQuestions && branchLocalQuestions.length > 0
|
||||
? branchLocalQuestions
|
||||
: ((graph?.nodes || []).filter(
|
||||
(n) => n.kind === "unknown" && n.status !== "resolved" && !doneForNowIds.includes(n.id),
|
||||
));
|
||||
if (openNodes.length <= 1) return null;
|
||||
|
||||
return (
|
||||
@@ -880,6 +897,23 @@ export default function ReasoningWorkspace({
|
||||
{/* Invitation — shows when selected but no content yet */}
|
||||
{isSelected && !hasFocusedContent() && (
|
||||
<div className="mt-3 space-y-3">
|
||||
{/* Branch-local contribution scoped to this question */}
|
||||
{(experimentalBranchContributions?.length ?? 0) > 0 && (
|
||||
(() => {
|
||||
const qContribs = experimentalBranchContributions.filter(
|
||||
c => node.id === c.questionId,
|
||||
);
|
||||
if (!qContribs.length) return null;
|
||||
return (
|
||||
<div className="rounded-lg border border-gray-200/80 bg-gray-50/60 px-4 py-3">
|
||||
<h3 className="mb-1 text-[10px] font-semibold tracking-widest uppercase text-gray-400">
|
||||
Contribution
|
||||
</h3>
|
||||
<p className="text-sm leading-relaxed text-gray-700">{qContribs[0].text}</p>
|
||||
</div>
|
||||
);
|
||||
})()
|
||||
)}
|
||||
<p className="text-sm leading-relaxed text-gray-500">
|
||||
We have not explored this yet. Do you want to work through it?
|
||||
</p>
|
||||
@@ -1040,28 +1074,31 @@ export default function ReasoningWorkspace({
|
||||
</div>
|
||||
)}
|
||||
|
||||
<button
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
setFocusedPresentationItemId(null);
|
||||
}}
|
||||
style={{ cursor: "pointer" }}
|
||||
className="text-sm text-gray-400 underline hover:text-gray-600 transition"
|
||||
>
|
||||
Back to open questions
|
||||
</button>
|
||||
{/* Footer controls — horizontally separated (RTO.26B) */}
|
||||
<div className="mt-4 mb-3 flex items-center justify-between gap-4">
|
||||
<button
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
setFocusedPresentationItemId(null);
|
||||
}}
|
||||
style={{ cursor: "pointer" }}
|
||||
className="text-sm text-gray-400 underline hover:text-gray-600 transition whitespace-nowrap"
|
||||
>
|
||||
Back to open questions
|
||||
</button>
|
||||
|
||||
<button
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
setFocusedPresentationItemId(null);
|
||||
setDoneForNowIds((prev) => [...prev, node.id]);
|
||||
}}
|
||||
style={{ cursor: "pointer" }}
|
||||
className="rounded-lg border border-gray-300 bg-white px-4 py-2 text-sm font-medium text-gray-600 hover:bg-gray-50 transition"
|
||||
>
|
||||
Done for now
|
||||
</button>
|
||||
<button
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
setFocusedPresentationItemId(null);
|
||||
setDoneForNowIds((prev) => [...prev, node.id]);
|
||||
}}
|
||||
style={{ cursor: "pointer" }}
|
||||
className="rounded-lg border border-gray-300 bg-white px-4 py-2 text-sm font-medium text-gray-600 hover:bg-gray-50 transition whitespace-nowrap"
|
||||
>
|
||||
Done for now
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
})()}
|
||||
@@ -1180,7 +1217,18 @@ export default function ReasoningWorkspace({
|
||||
{/* ── Right lane: stable supporting reference ───────── */}
|
||||
{hasCurrentSummaryCondition && (
|
||||
<div className="space-y-6 lg:col-span-1">
|
||||
<OriginalSituation scenario={scenario} centralStatement={graph?.centralStatement} />
|
||||
{/* RTO.26B — situation card from scenario text when no graph */}
|
||||
{!graph && scenario && (
|
||||
<div className="rounded-lg border border-gray-200/60 bg-gray-50/40 px-5 py-4">
|
||||
<h2 className="mb-2 text-[11px] font-semibold tracking-widest uppercase text-gray-500">
|
||||
Situation
|
||||
</h2>
|
||||
<p className="whitespace-pre-wrap text-sm leading-relaxed text-gray-600">
|
||||
{scenario}
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
{graph && <OriginalSituation scenario={scenario} centralStatement={graph?.centralStatement} />}
|
||||
{/* RTO.25B — temporarily hidden to reduce competing navigation while branch-experiment is active */}
|
||||
<div className="hidden">
|
||||
<InvestigationMap turnCount={investigationHistory.length} />
|
||||
|
||||
Reference in New Issue
Block a user