22 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.
Facilitator View Projection (Experiment 12)
Version C derives its content from existing graph fields without requiring new backend data. The following fields are used as inputs:
| Input | Source |
|---|---|
| node type / kind | node.kind (observation, unknown, assumption, state, metric, conclusion) |
| node label or description | node.label, node.description |
| support / status | node.status, resolvedNodeIds |
| confidence where available | node.confidence |
| active unknown identity | graph.activeUnknownNodeId |
| resolution state | node.status === "resolved" or resolvedNodeIds.includes(id) |
| evidence references where available | node.evidenceIds (currently empty in mocks) |
| relationship relevance where available | edge.relevance, node.relationships |
Current limitations (observations, not requests)
The following are observed constraints of the current graph output. They are documented here because they affect the adapter's filtering and ranking logic. They should NOT be treated as backend change requests during this experiment.
- Graph text may repeat the full original scenario verbatim in node labels or descriptions.
- Labels may be verbose relative to what a user can scan quickly.
- The selected question rationale and the selected question itself may diverge slightly in wording from the underlying unknown node.
- Ranking signals (relevance, priority) may not be sufficient for ideal user-facing ordering; the adapter uses deterministic fallbacks.
- Some assumptions may be too generic to be useful without context.
- Duplicate semantic content may occur across node types (e.g., an observation and an unknown restating the same scenario fragment).
The adapter handles these limitations through:
- Length-based filtering of overly verbose items;
- Normalised text deduplication across node kinds;
- Deprioritisation of items matching known boilerplate patterns;
- Deterministic ranking with explicit fallback ordering documented in code comments.