# Task: Fix AI design history loading stall ## Identity - Task ID: 20260819-history-load-stall-a92d - Mode: Feature - Branch: codex/20260819-history-load-stall-a92d-history-load-stall - Worktree: D:\mk-history-load-stall-a92d - Base commit: abece81fdb178711d4dcbe1f87b987f54d71d6dd - Owner: codex-root - Status: Completed ## Scope - Replace full-history AI Design conversation loading with a cursor-paginated latest-message flow. - Ensure workspace history becomes visible before generation-task reconciliation completes. - Make rapid conversation switching safe when an event-stream connection is still pending. - Update the local and Works Square adapters, shared boundary, main-process route, renderer store/canvas, and focused tests as needed. ## Intent And Constraints - Initial conversation reads return the newest 10 message records; scrolling upward requests older pages and preserves viewport position. - Do not retain or transmit an unbounded message history through the normal conversation API, mutation payloads, or snapshots. - Preserve the existing workspace/conversation identity checks and do not apply stale responses after a switch. - A pending connection attempt is treated as owned until it settles or is explicitly aborted; returning A -> B -> A must not create duplicate pending streams for A. - Server and desktop client contracts must remain explicit and bounded; page cursor contents are opaque to the renderer. ## Outcome - The renderer shows a selected Conversation as soon as its Workspace response arrives; delayed or failed generation-task reconciliation can no longer keep the history view on its loading state. - Conversation history is cursor-paginated end to end: the initial page is the newest 10 messages, scrolling upward loads one older page at a time, de-duplicates stable message IDs, and retains viewport position. - Local and Works Square adapters expose the same page metadata. The Main route forwards the opaque cursor without interpreting it. - Rapid A → B → A switching reuses an in-flight A event-stream attempt instead of opening another non-cancellable request. Renderer disconnection while Main is still opening a relay now closes the eventual subscription, and an upstream WebSocket open is bounded by a 10-second timeout. ## Verification - `pnpm test` — 183 files and 2167 tests passed. - `pnpm exec vitest run tests/unit/image-workspace-api.test.ts tests/unit/image-workspace-store.test.ts tests/unit/local-image-workspace.test.ts tests/unit/works-square-design-workspace.test.ts tests/unit/image-workspace-route.test.ts tests/unit/image-canvas-page.test.tsx --reporter=dot` — 154 passed. The Canvas suite still reports three pre-existing React `act(...)` warnings in its stale-auth test. - `pnpm run typecheck` — passed. - `pnpm exec eslint electron/api/routes/image-workspace.ts electron/image-workspace/local-workspace.ts electron/image-workspace/module.ts electron/image-workspace/works-square-workspace.ts shared/image-workspace.ts src/lib/image-workspace.ts src/pages/ImageCanvas/index.tsx src/stores/image-workspace.ts tests/unit/image-workspace-route.test.ts tests/unit/image-workspace-store.test.ts tests/unit/local-image-workspace.test.ts tests/unit/works-square-design-workspace.test.ts tests/unit/image-workspace-api.test.ts` — passed. - `git diff --check` — passed. ## Follow-ups - Main-branch promotion is pending release of the repository-wide integration lock held by task `20260819-merge-performance-package-6e5a`. ## Promotion Candidates - None recorded.