# v0.7 — Mock Investigation Mode for UI Development ## Purpose A local mock/demo mode lets you develop and test the Confidence Engine UI without running Ollama. It intercepts API calls at the frontend layer and replays pre-recorded scenario fixtures, producing identical response shapes whether real or mocked. ## Quick Start ```bash # Enable mock mode export NEXT_PUBLIC_CONFIDENCE_ENGINE_MOCKS=true # Optional: choose a delay profile (default: normal = 700ms) export NEXT_PUBLIC_CONFIDENCE_MOCK_DELAY=normal # instant | normal | slow # Optional: choose a scenario (default: complete = jumps to end after start) export NEXT_PUBLIC_CONFIDENCE_ENGINE_MOCK_SCENARIO=complete # complete | error | "" npm run dev ``` Navigate to the confidence-engine UI and enter any scenario text — the response will come from fixtures, not Ollama. ## Environment Variables | Variable | Required | Values | Default | Description | |---|---|---|---|---| | `NEXT_PUBLIC_CONFIDENCE_ENGINE_MOCKS` | yes | `"true"` or anything else | disabled | Enables mock mode when set to `"true"` | | `NEXT_PUBLIC_CONFIDENCE_MOCK_DELAY` | no | `"instant"`, `"normal"`, `"slow"` | `"normal"` (700ms) | Simulated latency for realistic loading UX | | `NEXT_PUBLIC_CONFIDENCE_ENGINE_MOCK_SCENARIO` | no | `"complete"`, `"error"`, `""` | `""` (sequential turns) | Which scenario to replay | ## Scenarios ### Default (Sequential Turns) Replays 6 turns of the "Complaints + Production" investigation: | Turn | What happens | |------|-------------| | 0 | Start — two observations, three unknown nodes. Question: *"Were both percentages calculated from comparable baseline counts?"* | | 1 | User confirms same period → new observation added. Question: *"Did the complaint rate per unit produced improve or worsen?"* | | 2 | User provides baselines (100→135 complaints, 1000→1400 production) → new observation. Question: *"Was there any change in how complaints were recorded?"* | | 3 | User confirms rate improved (10/1000→9.6/1000) → new observation. Unknown `u-4` resolved by process of elimination. **no-question** — needs more evidence. | | 4 | *(not reached in default — shown only when stepping past turn 3)* | | 5 | User confirms same reporting rules → final completion with full summary. | After the initial analysis is submitted, each update call advances to the next turn. In `"complete"` mode, the first update jumps directly to turn 5 (final). ### Complete Mode (`NEXT_PUBLIC_CONFIDENCE_ENGINE_MOCK_SCENARIO=complete`) After the start response (turn 0), every subsequent update returns the final completion state (turn 5) immediately. Useful for quickly verifying end-to-end UI flow. ### Error Mode (`NEXT_PUBLIC_CONFIDENCE_ENGINE_MOCK_SCENARIO=error`) All API calls return a structured error response with: - `success: false` - `stage: "provider"` - `error: "Mock provider error: structured response unavailable."` - `providerErrors: [...]` Useful for testing the UI's error display paths. ## Architecture ``` ScenarioForm (client) ├── MOCK_ENABLED (compile-time env resolution via Next.js build injection) ├── useMockGlobals() → window.__MOCK_* runtime globals ├── mockFetch ──► lib/mocks/confidence-engine/mock-client.js │ └── Self-contained interceptor (no external deps, pure ESM) │ ├── handleStartCase() — returns turn 0 or error │ └── handleUpdateCase() — advances turns (0→5) └── fetch ────────────────► real API routes /api/cases/start | /api/cases/update ``` - **mock-client.js** is self-contained: all turn data is defined inline. It intercepts POST requests to `/api/cases/start` and `/api/cases/update`. Any other URL is passed through unchanged. - Uses `window.__MOCK_*` globals (set by `useMockGlobals()` hook in ScenarioForm) for runtime env access from the browser. Falls back to `process.env.*` on the server side. - **UI integration** in `scenario-form.jsx`: one compile-time boolean (`MOCK_ENABLED`), one React hook (`useMockGlobals`), two ternary replacements of `fetch`. No other components need changes. ## Mock Indicator When mock mode is active, a `"Mock mode active"` label appears inside the Developer details panel (bottom of the workspace). It does not appear in user-facing UI areas. The indicator uses `mockFetch`'s built-in guard: - In client components: reads from `window.__MOCK_ENABLED` (set by `useMockGlobals`). - The real API path is preserved — when mock mode is off, mockFetch simply delegates to native `fetch`. ## Files | File | Purpose | |---|---| | `lib/mocks/confidence-engine/mock-client.js` | Self-contained interceptor + 6-turn scenario data (pure ESM) | | `components/scenario-form.jsx` | Minimal integration: MOCK_ENABLED guard, useMockGlobals hook, mockFetch dispatch | | `.env.example` | Documented env var reference | | `docs/v0.7-ui-mock-mode.md` | This file | ## Safety Rules - **No secrets**: Mock fixtures contain only fictional scenario data. No API keys, passwords, or PII. - **No `.env.local` commit**: The `.gitignore` already excludes `.env.local`. Copy from `.env.example` for local overrides. - **Real path preserved**: Setting `NEXT_PUBLIC_CONFIDENCE_ENGINE_MOCKS` to anything other than `"true"` returns to the real Ollama API — zero code change needed. ## Turn Fixture Schema Each turn snapshot (inline in mock-client.js) contains: ```js { nodes: [{ id, label, description, kind, status, confidence, confidenceAssessment?, value?, unit?, evidenceIds?, dependsOn?, affects?, parentId?, childIds? }], edges: [{ id, fromNodeId, toNodeId, relationship, confidence, description }], resolved: string[], // IDs of nodes now marked "resolved" active: string | null, // ID of the current unknown node (or null) question: string | null, // Question text for this turn noQReason: string | null, // Why no question is asked (turns 4+ in complete mode) summary: string // Current summary text } ``` The situationGraph returned by the fixtures matches the real route response shape exactly, ensuring the UI renders identically.