feat: explore facilitated investigation workspace
Phase 4 UX exploration — workshop desk metaphor. Workspace layout changes: - Investigation Map promoted from preview to workspace artefact - Understanding card given wider surface (lg:col-span-2) - Grid shifts from equal-column to cognitive-weighted widths (lg:grid-cols-5) - Mobile remains stacked; tablet simplifies naturally - Desktop exploits wider working canvas Layout structured by cognitive activity: Active workspace zone (Question + Response) Supporting workspace (Understanding, Map) Reference row (Situation, History)
This commit is contained in:
@@ -84,10 +84,10 @@ export default function InvestigationMap({ turnCount = 0 }) {
|
|||||||
return (
|
return (
|
||||||
<div className="rounded-lg border border-gray-100 bg-gray-50/50 p-4" role="region" aria-label="Investigation map preview">
|
<div className="rounded-lg border border-gray-100 bg-gray-50/50 p-4" role="region" aria-label="Investigation map preview">
|
||||||
<h2 className="mb-1 text-sm font-semibold tracking-tight text-gray-400">
|
<h2 className="mb-1 text-sm font-semibold tracking-tight text-gray-400">
|
||||||
Investigation Map Preview
|
Investigation Map
|
||||||
</h2>
|
</h2>
|
||||||
<p className="mb-3 text-xs text-gray-400">
|
<p className="mb-3 text-xs text-gray-400">
|
||||||
This preview shows where a future reasoning map may appear. Its final shape will emerge from the reasoning engine.
|
Active investigation topics and their status.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<div className="space-y-px border-t border-gray-100 pt-3" role="list" aria-label="Investigation topics">
|
<div className="space-y-px border-t border-gray-100 pt-3" role="list" aria-label="Investigation topics">
|
||||||
|
|||||||
@@ -669,72 +669,100 @@ export default function ReasoningWorkspace({
|
|||||||
{/* Post-update acknowledgement — only after success, never during loading */}
|
{/* Post-update acknowledgement — only after success, never during loading */}
|
||||||
{updateStatus === "success" && !isUpdating && <UpdateAcknowledgement updateResult={result} />}
|
{updateStatus === "success" && !isUpdating && <UpdateAcknowledgement updateResult={result} />}
|
||||||
|
|
||||||
{/* ── Active workspace (left) + Working memory (right) ─────── */}
|
{/* ══════════════════════════════════════════════════════════
|
||||||
<div className="grid grid-cols-1 gap-6 md:grid-cols-2">
|
FACILITATED INVESTIGATION WORKSPACE — PHASE 4 EXPLORATION
|
||||||
{/* Left column — active workspace */}
|
══════════════════════════════════════════════════════════
|
||||||
<div className="space-y-6">
|
|
||||||
{/* ── Local update loading (always visible when updating) ─ */}
|
|
||||||
{isUpdating && (
|
|
||||||
<LoadingOverlay
|
|
||||||
isLoading={true}
|
|
||||||
elapsed={updateElapsed}
|
|
||||||
currentMessage={updateMsg}
|
|
||||||
variant="update"
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{/* ── Response form — hidden during update loading ─ */}
|
Layout metaphor: a workshop desk, not a document.
|
||||||
{!isUpdating && canAnswer && (
|
|
||||||
<form onSubmit={handleUpdateCaptureAndSubmit} className="space-y-4 rounded-lg border border-gray-200 bg-white p-5">
|
|
||||||
<div>
|
|
||||||
<label htmlFor="rw-answer" className="mb-2 block text-sm font-medium text-gray-700">
|
|
||||||
Response
|
|
||||||
</label>
|
|
||||||
<textarea
|
|
||||||
id="rw-answer"
|
|
||||||
value={answer}
|
|
||||||
onChange={(e) => setAnswer(e.target.value)}
|
|
||||||
rows={4}
|
|
||||||
disabled={updateStatus === "loading"}
|
|
||||||
className="w-full rounded-lg border border-gray-300 px-4 py-3 text-sm focus:border-gray-500 focus:outline-none focus:ring-2 focus:ring-gray-400 disabled:cursor-not-allowed disabled:opacity-60"
|
|
||||||
placeholder="Enter the answer to the selected question..."
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div className="flex items-center justify-between">
|
|
||||||
<p className="text-xs text-gray-400">
|
|
||||||
One update turn only in this prototype.
|
|
||||||
</p>
|
|
||||||
<button
|
|
||||||
type="submit"
|
|
||||||
disabled={!answer.trim()}
|
|
||||||
className="rounded-lg bg-blue-700 px-5 py-2.5 text-sm font-medium text-white transition hover:bg-blue-600 disabled:cursor-not-allowed disabled:opacity-40"
|
|
||||||
>
|
|
||||||
Update
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{/* ── Terminal state: outcome card — hidden during update loading ─ */}
|
Desktop: wide work surfaces organised by cognitive activity.
|
||||||
{!isUpdating && status === "success" && !hasSelectedQuestion && graph && genuineCompletion && (
|
Tablet: simplified two-zone layout.
|
||||||
|
Mobile: naturally stacked.
|
||||||
|
══════════════════════════════════════════════════════════ */}
|
||||||
|
|
||||||
|
{hasSelectedQuestion ? (
|
||||||
|
|
||||||
|
<>
|
||||||
|
{/* ── Active workspace zone (Question + Response) ───────── */}
|
||||||
|
<div className="space-y-6">
|
||||||
|
|
||||||
|
{isUpdating && (
|
||||||
|
<LoadingOverlay
|
||||||
|
isLoading={true}
|
||||||
|
elapsed={updateElapsed}
|
||||||
|
currentMessage={updateMsg}
|
||||||
|
variant="update"
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{!isUpdating && canAnswer && (
|
||||||
|
<form onSubmit={handleUpdateCaptureAndSubmit} className="space-y-4 rounded-lg border border-gray-200 bg-white p-5">
|
||||||
|
<div>
|
||||||
|
<label htmlFor="rw-answer" className="mb-2 block text-sm font-medium text-gray-700">
|
||||||
|
Response
|
||||||
|
</label>
|
||||||
|
<textarea
|
||||||
|
id="rw-answer"
|
||||||
|
value={answer}
|
||||||
|
onChange={(e) => setAnswer(e.target.value)}
|
||||||
|
rows={4}
|
||||||
|
disabled={updateStatus === "loading"}
|
||||||
|
className="w-full rounded-lg border border-gray-300 px-4 py-3 text-sm focus:border-gray-500 focus:outline-none focus:ring-2 focus:ring-gray-400 disabled:cursor-not-allowed disabled:opacity-60"
|
||||||
|
placeholder="Enter the answer to the selected question..."
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="flex items-center justify-between">
|
||||||
|
<p className="text-xs text-gray-400">
|
||||||
|
One update turn only in this prototype.
|
||||||
|
</p>
|
||||||
|
<button
|
||||||
|
type="submit"
|
||||||
|
disabled={!answer.trim()}
|
||||||
|
className="rounded-lg bg-blue-700 px-5 py-2.5 text-sm font-medium text-white transition hover:bg-blue-600 disabled:cursor-not-allowed disabled:opacity-40"
|
||||||
|
>
|
||||||
|
Update
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
)}
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* ── Supporting workspace (Understanding, Map, Situation) ─ */}
|
||||||
|
<div className="grid grid-cols-1 gap-6 lg:grid-cols-5">
|
||||||
|
|
||||||
|
{/* Understanding — wider surface (2 cols) */}
|
||||||
|
{hasCurrentSummaryCondition && (
|
||||||
|
<div className="lg:col-span-2">
|
||||||
|
<CurrentUnderstandingCard currentSummary={graph?.currentSummary || result?.updatedSituationGraph?.currentSummary} plainLanguage={propUnderstanding || null} />
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* Investigation Map — workspace artefact (1.5 cols) */}
|
||||||
|
{hasSelectedQuestion && (
|
||||||
|
<div className="lg:col-span-1">
|
||||||
|
<InvestigationMap turnCount={investigationHistory.length} />
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</>
|
||||||
|
|
||||||
|
) : status === "success" ? (
|
||||||
|
|
||||||
|
<>
|
||||||
|
{/* Terminal state */}
|
||||||
|
{genuineCompletion && (
|
||||||
<CompletionCard summary={resolveCurrentSummary(propUnderstanding || graph?.currentSummary || result?.updatedSituationGraph?.currentSummary)} />
|
<CompletionCard summary={resolveCurrentSummary(propUnderstanding || graph?.currentSummary || result?.updatedSituationGraph?.currentSummary)} />
|
||||||
)}
|
)}
|
||||||
{!isUpdating && status === "success" && !hasSelectedQuestion && graph && !genuineCompletion && (
|
{!genuineCompletion && (
|
||||||
<EvidenceLimitCard summary={resolveCurrentSummary(propUnderstanding || graph?.currentSummary || result?.updatedSituationGraph?.currentSummary)} />
|
<EvidenceLimitCard summary={resolveCurrentSummary(propUnderstanding || graph?.currentSummary || result?.updatedSituationGraph?.currentSummary)} />
|
||||||
)}
|
)}
|
||||||
|
</>
|
||||||
|
|
||||||
</div>
|
) : null}
|
||||||
|
|
||||||
{/* Right column — working memory: Understanding + Map */}
|
|
||||||
{hasSelectedQuestion && (
|
|
||||||
<div className="space-y-6">
|
|
||||||
{hasCurrentSummaryCondition && (
|
|
||||||
<CurrentUnderstandingCard currentSummary={graph?.currentSummary || result?.updatedSituationGraph?.currentSummary} plainLanguage={propUnderstanding || null} />
|
|
||||||
)}
|
|
||||||
<InvestigationMap turnCount={investigationHistory.length} />
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* ── Reference row — Situation + History side-by-side on desktop ─ */}
|
{/* ── Reference row — Situation + History side-by-side on desktop ─ */}
|
||||||
<div className="grid grid-cols-1 gap-6 md:grid-cols-2">
|
<div className="grid grid-cols-1 gap-6 md:grid-cols-2">
|
||||||
|
|||||||
@@ -0,0 +1,92 @@
|
|||||||
|
# Design Evolution Log
|
||||||
|
|
||||||
|
A chronological record of why significant design decisions were made. This is NOT a changelog. It records the product's evolution of thinking.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Phase 1
|
||||||
|
Simple conversational investigation
|
||||||
|
|
||||||
|
Question → Answer interaction.
|
||||||
|
|
||||||
|
Purpose:
|
||||||
|
Prove the reasoning loop.
|
||||||
|
|
||||||
|
Learning:
|
||||||
|
Conversation alone does not provide sufficient context during longer investigations.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Phase 2
|
||||||
|
Persistent investigation notebook
|
||||||
|
|
||||||
|
Added:
|
||||||
|
|
||||||
|
- current understanding
|
||||||
|
- original situation
|
||||||
|
- investigation history
|
||||||
|
|
||||||
|
Learning:
|
||||||
|
Users need persistent context rather than remembering previous answers.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Phase 3
|
||||||
|
Document workspace
|
||||||
|
|
||||||
|
Created a coherent workspace with:
|
||||||
|
|
||||||
|
- investigation status
|
||||||
|
- current investigation
|
||||||
|
- response
|
||||||
|
- understanding
|
||||||
|
- investigation map placeholder
|
||||||
|
- situation
|
||||||
|
- history
|
||||||
|
|
||||||
|
Learning:
|
||||||
|
The interface became usable but still behaved like a document rather than a workspace.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Phase 4 (Current Exploration)
|
||||||
|
Facilitated Investigation Workshop
|
||||||
|
|
||||||
|
Status:
|
||||||
|
Experimental.
|
||||||
|
|
||||||
|
Hypothesis:
|
||||||
|
|
||||||
|
The Confidence Engine is not:
|
||||||
|
|
||||||
|
- a chatbot
|
||||||
|
- a dashboard
|
||||||
|
- a form
|
||||||
|
|
||||||
|
It is a facilitated investigation workspace.
|
||||||
|
|
||||||
|
The interface should resemble the environment in which structured thinking happens.
|
||||||
|
|
||||||
|
Record discoveries rather than conclusions.
|
||||||
|
|
||||||
|
Leave room for future phases.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Phase 4 — Guiding Principles
|
||||||
|
|
||||||
|
The Confidence Engine is a workspace, not a document.
|
||||||
|
|
||||||
|
People think in multiple directions simultaneously.
|
||||||
|
|
||||||
|
Useful context should be visible together.
|
||||||
|
|
||||||
|
The interface should favour thinking over scrolling.
|
||||||
|
|
||||||
|
The workspace should feel like a large desk or workshop rather than a narrow report.
|
||||||
|
|
||||||
|
The engine facilitates thinking.
|
||||||
|
|
||||||
|
The user contributes evidence.
|
||||||
|
|
||||||
|
The workspace captures shared understanding.
|
||||||
Reference in New Issue
Block a user