diff --git a/components/experimental/branch-switcher.jsx b/components/experimental/branch-switcher.jsx
index 2abd32e..7270ca9 100644
--- a/components/experimental/branch-switcher.jsx
+++ b/components/experimental/branch-switcher.jsx
@@ -46,7 +46,7 @@ function NewIndicator({ visible }) {
/* ── Single branch row ─────────────────────────────────── */
-function BranchRow({ id, label, active, isNew, origin, onClick }) {
+function BranchRow({ id, label, active, isNew, isPaused, origin, onClick }) {
const isActive = Boolean(active);
return (
@@ -80,8 +80,18 @@ function BranchRow({ id, label, active, isNew, origin, onClick }) {
)}
- {/* Passive new-result indicator (only for inactive branches) */}
- {!isActive && }
+ {/* Passive indicators: pause + new */}
+
+ {!isActive && isPaused && (
+
+ Paused
+
+ )}
+ {!isActive && }
+
);
}
@@ -92,6 +102,7 @@ export default function ExperimentalBranchSwitcher({
branches = [],
activeBranchId,
branchNewResults = {},
+ branchPauseState = [],
onBranchSelect,
}) {
if (!branches.length) return null;
@@ -119,6 +130,7 @@ export default function ExperimentalBranchSwitcher({
label={branch.label}
active={activeBranchId === branch.id}
isNew={Boolean(branchNewResults[branch.id])}
+ isPaused={branchPauseState.includes(branch.id)}
origin={branch.origin}
onClick={() => onBranchSelect?.(branch.id)}
/>
diff --git a/components/reasoning-workspace.jsx b/components/reasoning-workspace.jsx
index c7475ae..e829bc4 100644
--- a/components/reasoning-workspace.jsx
+++ b/components/reasoning-workspace.jsx
@@ -351,9 +351,14 @@ function BranchNotebookContent({
openQuestions,
lateResults,
inactiveBranchNewResults,
+ doneForNowBranchIds,
+ onDoneForNow,
+ branchId,
}) {
const hasOpenItems = openQuestions && openQuestions.length > 0;
const hasContributions = contributions && contributions.length > 0;
+ const isPaused = doneForNowBranchIds?.includes(branchId) || false;
+ const isBranchActive = !isPaused;
return (
@@ -407,9 +412,35 @@ function BranchNotebookContent({
)}
- {/* Quiet state — only when there are no open items and no updates */}
+ {/* Done for now control — only when branch is not already paused */}
+ {isBranchActive && onDoneForNow && contributions.length > 0 && (
+
+ { e.stopPropagation(); onDoneForNow(); }}
+ 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
+
+
+ )}
+
+ {/* Quiet state */}
{!hasOpenItems && !lateResults?.length && (
-
+
+ {isPaused ? (
+ <>
+
+ Nothing more to add here right now
+
+
+ This branch is paused. Reasoning preserved — return when you have more information.
+
+ >
+ ) : (
+
+ )}
+
)}
);
@@ -805,6 +836,11 @@ export default function ReasoningWorkspace({
branchLocalContributions,
branchLocalLateResults,
inactiveBranchNewResults,
+ activeBranchIdForNotebook,
+ // ── RTO.27B — provisional pause state ──
+ doneForNowBranchIds,
+ onDoneForNow,
+ onReopenBranch,
}) {
const [investigationHistory, setInvestigationHistory] = useState([]);
const turnCounter = useRef(0);
@@ -1115,6 +1151,9 @@ export default function ReasoningWorkspace({
openQuestions={branchLocalQuestions || []}
lateResults={branchLocalLateResults || []}
inactiveBranchNewResults={inactiveBranchNewResults || {}}
+ doneForNowBranchIds={doneForNowBranchIds || []}
+ onDoneForNow={onDoneForNow}
+ branchId={activeBranchIdForNotebook}
/>
)}
@@ -1149,14 +1188,12 @@ export default function ReasoningWorkspace({
{genuineCompletion && (
)}
- {!genuineCompletion && (
- experimentalBranches && experimentalBranches.length > 0 ? (
- // In experiment mode: quiet facilitator state, not evidence limit verdict
-
- ) : (
-
- )
- )}
+ {!genuineCompletion && experimentalBranches && experimentalBranches.length > 0 ? (
+ // Quiet state is handled inside BranchNotebookContent for experiment mode
+ null
+ ) : !genuineCompletion ? (
+
+ ) : null}
>
)}
diff --git a/components/scenario-form.jsx b/components/scenario-form.jsx
index 20e9980..d2f3864 100644
--- a/components/scenario-form.jsx
+++ b/components/scenario-form.jsx
@@ -229,6 +229,10 @@ export default function ScenarioForm() {
// Pre-seed Competitor development with a late result for RTO.27A testing
const [branchNewResults, setBranchNewResults] = useState({ "branch-a": true });
+ /* ── RTO.27B — provisional done-for-now state (experimental) ── */
+
+ const [doneForNowBranchIds, setDoneForNowBranchIds] = useState([]);
+
/* ── RTO.26B — experimental branch-scoped reasoning fixture ───── */
const branchScoped = useBranchScopedFixture();
@@ -270,15 +274,22 @@ export default function ScenarioForm() {
}, [activeBranch, branchScoped]);
// Determine which non-active branches have new results for passive indicator
+ // (RTO.27B: also include done-for-now branches so pause state is visible)
const inactiveBranchNewResults = useMemo(() => {
const result = {};
BRANCHES.forEach(b => {
- if (b.id !== activeBranchId && b.id in branchNewResults) {
- result[b.id] = true;
+ if (b.id !== activeBranchId) {
+ if (b.id in branchNewResults) {
+ result[b.id] = true;
+ }
+ // Show pause indicator on any done-for-now branch
+ if (doneForNowBranchIds.includes(b.id)) {
+ result[b.id] = true;
+ }
}
});
return result;
- }, [activeBranchId, BRANCHES, branchNewResults]);
+ }, [activeBranchId, BRANCHES, branchNewResults, doneForNowBranchIds]);
/* Restore persisted session on mount (Phase 3) ─────────── */
useEffect(() => {
@@ -472,6 +483,17 @@ export default function ScenarioForm() {
branchLocalContributions={experimentalBranchContributions.length > 0 ? experimentalBranchContributions : undefined}
branchLocalLateResults={experimentalBranchLateResults.length > 0 ? experimentalBranchLateResults : undefined}
inactiveBranchNewResults={Object.keys(inactiveBranchNewResults).length > 0 ? inactiveBranchNewResults : undefined}
+ activeBranchIdForNotebook={activeBranchId}
+ doneForNowBranchIds={doneForNowBranchIds}
+ onDoneForNow={() => {
+ if (activeBranchId && !doneForNowBranchIds.includes(activeBranchId)) {
+ setDoneForNowBranchIds(prev => [...prev, activeBranchId]);
+ }
+ }}
+ onReopenBranch={(id) => {
+ setDoneForNowBranchIds(prev => prev.filter(x => x !== id));
+ setActiveBranchId(id);
+ }}
onRestart={() => { setStatus("idle"); setResult(null); setScenario(""); }}
/>
);
@@ -484,14 +506,30 @@ export default function ScenarioForm() {
branches={BRANCHES}
activeBranchId={activeBranchId}
branchNewResults={branchNewResults}
+ branchPauseState={doneForNowBranchIds}
onBranchSelect={(id) => {
- if (id !== activeBranchId) {
- setActiveBranchId(id);
+ if (id === activeBranchId) return;
+ // Reopen: if the selected branch is paused, clear its pause state
+ if (doneForNowBranchIds.includes(id)) {
+ setDoneForNowBranchIds(prev => prev.filter(x => x !== id));
}
+ setActiveBranchId(id);
}}
/>
+ {/* ── RTO.27B — simulated late update for paused branch (experimental dev control) ─ */}
+
+ {
+ // Simulate a late result arriving on the customer-demand branch while paused
+ setBranchNewResults(prev => ({ ...prev, "branch-b": true }));
+ }}
+ className="rounded border border-purple-200/60 bg-purple-50 px-3 py-1.5 text-xs text-purple-700 hover:bg-purple-100 transition"
+ >
+ Simulate late update on Customer demand
+
+
>
)}
@@ -669,6 +707,17 @@ export default function ScenarioForm() {
branchLocalContributions={experimentalBranchContributions.length > 0 ? experimentalBranchContributions : undefined}
branchLocalLateResults={experimentalBranchLateResults.length > 0 ? experimentalBranchLateResults : undefined}
inactiveBranchNewResults={Object.keys(inactiveBranchNewResults).length > 0 ? inactiveBranchNewResults : undefined}
+ activeBranchIdForNotebook={activeBranchId}
+ doneForNowBranchIds={doneForNowBranchIds}
+ onDoneForNow={() => {
+ if (activeBranchId && !doneForNowBranchIds.includes(activeBranchId)) {
+ setDoneForNowBranchIds(prev => [...prev, activeBranchId]);
+ }
+ }}
+ onReopenBranch={(id) => {
+ setDoneForNowBranchIds(prev => prev.filter(x => x !== id));
+ setActiveBranchId(id);
+ }}
onRestart={() => {
clearSession();
setStatus("idle");
@@ -691,11 +740,14 @@ export default function ScenarioForm() {
branches={BRANCHES}
activeBranchId={activeBranchId}
branchNewResults={branchNewResults}
+ branchPauseState={doneForNowBranchIds}
onBranchSelect={(id) => {
- /* User intentionally navigates — nothing more */
- if (id !== activeBranchId) {
- setActiveBranchId(id);
+ if (id === activeBranchId) return;
+ // Reopen: if the selected branch is paused, clear its pause state
+ if (doneForNowBranchIds.includes(id)) {
+ setDoneForNowBranchIds(prev => prev.filter(x => x !== id));
}
+ setActiveBranchId(id);
}}
/>