diff --git a/components/reasoning-workspace.jsx b/components/reasoning-workspace.jsx index e829bc4..d1df483 100644 --- a/components/reasoning-workspace.jsx +++ b/components/reasoning-workspace.jsx @@ -362,17 +362,28 @@ function BranchNotebookContent({ return (
- {/* Why this branch exists */} + {/* Why this branch exists — origin question is primary */} {branchContext && (

- Current branch + Investigating

-

{branchContext.label}

- {branchContext.origin && ( -

- Trying to understand: {branchContext.origin} -

+ {branchContext.originQuestion ? ( + <> +

{branchContext.originQuestion.text}

+ {branchContext.label && branchContext.originQuestion.text !== branchContext.label && ( +

Branch: {branchContext.label}

+ )} + + ) : branchContext.origin ? ( + <> +

{branchContext.label}

+

+ Trying to understand: {branchContext.origin} +

+ + ) : ( +

{branchContext.label}

)}
)} diff --git a/components/scenario-form.jsx b/components/scenario-form.jsx index 6cbc898..744eef5 100644 --- a/components/scenario-form.jsx +++ b/components/scenario-form.jsx @@ -237,8 +237,8 @@ export function derivePrimarySurface(result, status, showExperimentView, scenari const valid = hasValidInvestigationContext(result, status, scenario); - // RTO.28A: show branch-selection surface when investigation exists but no branch is active - if (showExperimentView && valid && !activeBranchId) return "BRANCH_SELECTION"; + // RTO.28B: show question-selection surface when investigation exists but no question/branch is active + if (showExperimentView && valid && !activeBranchId) return "QUESTION_SELECTION"; if (showExperimentView && valid) return "EXPERIMENT_NOTEBOOK"; if (!showExperimentView && valid) return "NORMAL_WORKSPACE"; @@ -283,6 +283,15 @@ export default function ScenarioForm() { // Use fixture branches as the authoritative source when available const BRANCHES = useMemo(() => branchScoped.getBranches(), [branchScoped]); + // Track the originating question for provenance + const [originQuestion, setOriginQuestion] = useState(null); + + // Extract inferred questions from the fixture (flat list for post-Analyse surface) + const inferredQuestions = useMemo(() => { + if (!branchScoped || typeof branchScoped.getAllInferredQuestions !== 'function') return []; + return branchScoped.getAllInferredQuestions(); + }, [branchScoped]); + // Simulate a late semantic result arriving on Branch A ~2s after a graph loads useEffect(() => { if (status !== "success" && status !== "error") return; @@ -538,7 +547,7 @@ export default function ScenarioForm() { <> {!activeBranchId ? ( - /* RTO.28A: no active branch — show branch-selection surface */ + /* RTO.28B: inferred questions surface — user chooses what to investigate */
{/* Situation remains visible */} @@ -552,25 +561,30 @@ export default function ScenarioForm() { )}
- {/* Branch selection */} + {/* Inferred questions — user chooses what to investigate */}
-

Choose a branch to continue

-

These are the current lines of inquiry. Pick whichever you want to work on.

+

Questions to explore

+

Click a question to start investigating. A branch will be created for your choice.

- {BRANCHES.map((branch) => ( + {inferredQuestions.map((q) => ( ))} + + {inferredQuestions.length === 0 && ( +

No questions available yet.

+ )}
) : ( @@ -592,7 +606,7 @@ export default function ScenarioForm() { setAnswer={() => {}} onAnswerSubmit={async (e) => e.preventDefault()} lastSubmittedAnswer="" - branchContext={branchContext} + branchContext={{ ...branchContext, originQuestion: originQuestion }} experimentalBranches={BRANCHES.length > 0 ? BRANCHES : undefined} branchLocalQuestions={experimentalBranchQuestions.length > 0 ? experimentalBranchQuestions : undefined} branchLocalContributions={experimentalBranchContributions.length > 0 ? experimentalBranchContributions : undefined} diff --git a/lib/fixtures/rto26b-branch-scoped.mjs b/lib/fixtures/rto26b-branch-scoped.mjs index d759db3..fb2c69d 100644 --- a/lib/fixtures/rto26b-branch-scoped.mjs +++ b/lib/fixtures/rto26b-branch-scoped.mjs @@ -190,6 +190,21 @@ export function useBranchScopedFixture() { return Object.values(BRANCH_META).map(m => ({ ...m })); }, + /** Return all inferred questions across branches (flat list for post-Analyse surface). */ + getAllInferredQuestions() { + const qA1 = this._qA1; + const qA2 = this._qA2; + const qB1 = this._qB1; + const qB2 = this._qB2; + if (!qA1 || !qA2 || !qB1 || !qB2) return []; + return [ + { id: qA1.id, text: qA1.text, branchId: "branch-competitor-development" }, + { id: qA2.id, text: qA2.text, branchId: "branch-competitor-development" }, + { id: qB1.id, text: qB1.text, branchId: "branch-customer-demand" }, + { id: qB2.id, text: qB2.text, branchId: "branch-customer-demand" }, + ]; + }, + /** Return all records (for verification / debugging). */ getAllRecords() { return allRecords;