20 KiB
Reasoning Contract Backlog
This document tracks every field that the UI currently mocks because the reasoning engine does not yet provide it. Each row maps a UI need to the temporary workaround and the desired eventual contract.
Legend
| Column | Purpose |
|---|---|
| Feature | The UX / component that needs this field |
| UI need | What the interface is trying to communicate |
| Temporary mock | How the UI fakes or derives the value today |
| Desired output | What the reasoning engine should eventually emit |
| Likely stage | Which reasoning phase would naturally produce this data |
| Notes | Context, constraints, open questions |
Status / State
| Feature | UI need | Temporary mock | Desired reasoning output | Likely stage | Notes |
|---|---|---|---|---|---|
| InvestigationSummaryPanel | Current status indicator (investigating / complete / evidence_limit) | Derives from selectedQuestion existence + resolvedNodeIds count |
Explicit status enum: "investigating", "resolution_achieved", "evidence_limit_reached" |
Post-investigation finalisation | Should be emitted after the engine decides there are no more useful questions |
| InvestigationSummaryPanel | Elapsed time since last update | Computes Date.now() - result.updatedAt |
Engine-provided lastUpdatedAt on every turn |
Every API response | UI already stores this; needs confirmation from reasoning |
Understanding / Summaries
| Feature | UI need | Temporary mock | Desired reasoning output | Likely stage | Notes |
|---|---|---|---|---|---|
| CurrentUnderstandingCard, InvestigationSummaryPanel | Durable plain-language synthesis of current state | result.summary → falls back to graph.currentSummary |
A single summary string that represents the latest synthesis |
Final summary step; updated at each turn end | Must be stable across refreshes; separate from graph data |
| CurrentUnderstandingCard | Filter technical summaries from plain-language ones | Heuristic regex against keywords (nodes, edges, by_kind) |
Boolean isPlainLanguageSummary flag or guaranteed plain-language field |
Every turn | Regex is fragile; engine should guarantee output quality |
Questions & Unknowns
| Feature | UI need | Temporary mock | Desired reasoning output | Likely stage | Notes |
|---|---|---|---|---|---|
| InvestigationSummaryPanel | Questions answered count | Counts unknown nodes with status === "resolved" or in resolvedNodeIds |
Explicit list of resolvedUnknownIds from engine |
Post-each turn | Current heuristic conflates structural resolution with questioning |
| InvestigationSummaryPanel | Still working on count | total unknowns - resolved |
Total identified unknowns minus resolved | Finalisation | Should not imply 1 unknown = 1 question |
| ReasoningWorkspace | Active question (next useful) | selectedQuestion.question from start/update API |
Same — but engine should guarantee a question exists when status === "investigating" |
Question selection phase | If no question is available, engine should emit evidence_limit_reached instead |
| ScenarioForm | Selected question reason / "why this matters" | selectedQuestion.reason from fixture |
Same — but guaranteed on every turn | Question selection | Already partially wired; just needs consistent coverage |
| ReasoningWorkspace | Question reasoning pattern metadata | selectedQuestion.reasoningPattern |
Engine should emit the pattern class for UI display (e.g. "comparability_check") | Question selection | Used in Developer details; could also inform UI tooltips |
Graph & Evidence
| Feature | UI need | Temporary mock | Desired reasoning output | Likely stage | Notes |
|---|---|---|---|---|---|
| SituationGraphView | Node confidence values | Mock confidence ("low"/"medium"/"high") |
Computed confidence per node from evidence weight | Graph construction | UI displays as indicators; needs numeric or ordinal source |
| SituationGraphView | Confidence assessment breakdown | confidenceAssessment.evidenceConfidence, completenessStatus, conclusionConfidence |
Structured confidence assessment with sub-scores | Evidence analysis | Currently flat mock object |
| DeveloperDetails | Active unknown node ID | graph.activeUnknownNodeId from fixture |
Explicit active target for next investigation step | Question selection | Internal reference; exposed via developer view only |
| ReasoningWorkspace | Newly surfaced unknown nodes | Scenarios provide proposal.addedNodes or mocks a static list |
Engine emits newlySurfacedNodeIds per turn |
Each update turn | UI highlights these to show what the investigation discovered |
| ScenarioForm | Node kind discrimination (observation / assumption / conclusion / unknown) | Hardcoded kind values in mock fixtures | Engine classifies each node correctly | Graph construction | Critical for correct display and reasoning traceability |
| ScenarioForm | Edge relationships | Mock relationship ("supports", "undermines") |
Engine emits relationship type between nodes | Graph construction | Needed for developer view; affects UI if confidence model expands |
Evidence & Resolution Tracking
| Feature | UI need | Temporary mock | Desired reasoning output | Likely stage | Notes |
|---|---|---|---|---|---|
| DeveloperDetails | evidenceIds per node |
Empty array [] in every mock node |
List of evidence nodes supporting this node | Graph construction | Needed for traceability in developer view |
| DeveloperDetails | dependsOn / affects per node |
Empty arrays [] in mock nodes |
Dependency and effect edges | Graph construction | Shows reasoning structure; currently hidden in collapsed developer details |
| InvestigationSummaryPanel | Whether evidence limit has been reached (terminal state) | Infers from activeUnknownNodeId === null + unresolved unknowns present |
Explicit terminal status flag from engine | Post-evaluation | UI shows "Current evidence limit reached" card |
| ReasoningWorkspace | resolvedNodeIds from update |
Mocked from scenario fixture; mirrors resolved unknown IDs | Engine emits resolvedUnknownNodeIds per turn |
Update response | Used to mark answered questions in history |
| ReasoningWorkspace | affectedNodeIds from update |
Empty array in mock | List of nodes changed by this answer | Update response | Developer view; shows ripple effects |
Diagnostics & Technical Metadata
| Feature | UI need | Temporary mock | Desired reasoning output | Likely stage | Notes |
|---|---|---|---|---|---|
| DiagnosticsView | promptVersion |
Hardcoded "v0.4" in mocks |
Actual prompt version used for this turn | Every request | Useful for debugging and rollout tracking |
| DiagnosticsView | modelName |
Hardcoded "mock-ollama" |
Actual model identifier | Every request | Needed when multiple models are supported |
| DiagnosticsView | responseDurationMs |
Zeroed in mocks | Actual response duration | Every request | Shows user how long reasoning took |
| DiagnosticsView | validationStatus |
Hardcoded "valid" |
Whether the output passed structured-validation | Post-processing | UI already uses this to decide if graph was parsed |
| DeveloperDetails | proposal details (addedNodes, updatedNodes) |
Mocked from scenario fixture | Full proposal metadata from reasoning engine | Update response | Shows what changed and why |
Recovery & Error States
| Feature | UI need | Temporary mock | Desired reasoning output | Likely stage | Notes |
|---|---|---|---|---|---|
| ReasoningWorkspace (ProviderUnavailableCard) | Detect provider/network failure | Regex on error string (provider, unavailable) |
Explicit providerAvailable: false flag or HTTP status |
Request time | Should distinguish transient from permanent failures |
| ReasoningWorkspace (MalformedResponseCard) | Detect unstructured / invalid JSON response | Regex on error string (malformed, parse, structured) |
Explicit validationError object with path details |
Post-processing | UI needs to know the validation failure for debugging |
| ReasoningWorkspace (UnexpectedStateCard) | Detect internal engine error | stage === "unexpected" from mock |
Engine-specific error code + recoverable flag | Any stage | Should distinguish recoverable vs unrecoverable errors |
Investigation Lifecycle
| Feature | UI need | Temporary mock | Desired reasoning output | Likely stage | Notes |
|---|---|---|---|---|---|
| InvestigationSummaryPanel | investigationStartedAt timestamp |
Uses result.updatedAt (from session storage) |
Engine-provided investigationStartedAt on start response |
Start case | Currently uses last-updated time as fallback; inaccurate |
| InvestigationSummaryPanel | lastUpdatedAt timestamp |
Session updatedAt persisted by UI |
Engine-provided timestamp on every update response | Every turn | UI already tracks this via session hook |
| ReasoningWorkspace | Genuine completion detection | Heuristic: all unknowns resolved + no active question | Explicit genuineCompletion: true from engine |
Post-evaluation | Should distinguish "everything resolved" from "stalled" |
| CompletionCard | Final summary for complete state | propUnderstanding or graph.currentSummary |
Engine-emitted final conclusion when all unknowns are resolved | Finalisation | Distinct from intermediate summaries |
| EvidenceLimitCard | Final summary at evidence limit | Same as above | Engine-emitted terminal summary when no more questions are useful | Finalisation | UI card style differs from CompletionCard |
Scenario & Central Statement
| Feature | UI need | Temporary mock | Desired reasoning output | Likely stage | Notes |
|---|---|---|---|---|---|
| OriginalSituation | Central statement display | scenario prop (user input) or graph.centralStatement |
Engine-derived central statement from user input | Start case | UI already handles both; engine should normalise |
| DeveloperDetails | Node descriptions | Mock nodes have label === description |
Distinct, detailed description per node | Graph construction | Current mock uses label as description; separate fields needed |
Investigation Map (Workspace UX)
Open design decision — final map shape intentionally unresolved
The current Investigation Map implementation exists only to validate:
- placement within the workspace;
- information density at preview scale;
- status presentation (established / current / unknown);
- responsive layout across viewports;
- interaction with surrounding components across turns.
It is NOT a committed design. The eventual map should be derived from the reasoning engine, not from hard-coded UI categories.
The following are unresolved design questions — do NOT treat them as agreed contract fields:
- Will the engine provide a flat topic list, hierarchy, branches, or grouped clusters?
- Who determines ordering — engine or user interaction?
- Will there be evidence counts, completion percentages, or path metadata?
- How does the map handle dynamic addition/removal of topics during investigation?
Current entry (temporary)
| Feature | UI need | Temporary mock | Desired reasoning output | Likely stage | Notes |
|---|---|---|---|---|---|
| InvestigationMap | Visible investigation progress | mock-only placeholder: minimal set of neutral topic names (≤5) with manual turn-based status progression | Engine emits investigationTopics: [{ title, status, ordering?, evidenceCount? }] |
Each turn — start and update response | UI displays topics in engine-determined order; statuses: "established" / "current" / "unknown" |
| InvestigationMap | Topic status evolution across turns | mock-only placeholder: Hardcoded PROGRESSION array indexed by investigationHistory.length |
Engine determines which topics are established, active, or unknown at each turn | Question selection phase | Topics should not expose graph internals; plain-language labels only |
The current adapter (lib/map/investigation-map-adapter.js) uses generic placeholder names (e.g. "Starting point", "Current focus") explicitly because they do NOT represent a domain-specific design decision.
Open Questions / Future Work
-
Structured confidence scores: The UI currently mocks ordinal confidence (low/medium/high). The reasoning engine should eventually emit numeric confidence values per node and a computed conclusion confidence, enabling richer visual indicators.
-
Evidence provenance: Nodes mock empty
evidenceIds. The engine should emit which observation nodes support each assumption/conclusion, enabling the developer view to show full evidence chains. -
Turn-level diagnostics: Currently only basic validation metadata is mocked. Full turn diagnostics (prompt used, model, duration, temperature, validation results) would help debugging and monitoring.
-
Terminal state semantics: The UI distinguishes "resolution_achieved" from "evidence_limit_reached" using heuristics. The engine should emit explicit terminal states so the UI can show the appropriate card without inference.
-
Session integrity: The session persistence hook (Phase 3) stores
situationGraph+selectedQuestion+summary. If the engine later emits additional fields that affect the UI (e.g.,investigationStartedAt,genuineCompletion), the persisted payload should expand to include them. -
Recovery action granularity: The recovery cards currently offer a single "restart investigation" action. Future engine contracts could support partial recovery (e.g., retry with different parameters, switch models) rather than full restart.
-
Investigation duration tracking: The summary panel computes elapsed time from
Date.now() - updatedAt. If the engine emits proper timestamps, the UI can show accurate elapsed duration and investigate stalls (>5 min between turns). -
Layout independence (v0.7 workspace layout phase): Reasoning outputs must remain entirely independent of presentation layout. The UI's responsive workspace layout — which progressively reveals simultaneous context on wide screens — is a pure presentation concern. No reasoning contract field should be added, removed, or modified to accommodate layout changes. Future reasoning outputs should carry data semantically; how that data arranges itself visually is the responsibility of the presentation layer alone.