Tasks: Fix Audit Chat Active Conversation Preservation
Input: Design documents from /specs/093-fix-audit-chat-active-preserve/
Prerequisites: plan.md (complete), spec.md (complete), research.md (complete), data-model.md (complete)
Tests: Included — constitution requires test-first quality gates (VII).
Organization: Tasks grouped by user story. Both stories are P1 and share the same source file, so they execute sequentially.
Format: [ID] [P?] [Story] Description​
- [P]: Can run in parallel (different files, no dependencies)
- [Story]: Which user story this task belongs to (e.g., US1, US2)
- Exact file paths included in descriptions
Path Conventions​
- UI source:
ui/src/store/chat-store.ts - UI tests:
ui/src/store/__tests__/chat-store.test.ts
Phase 1: Setup​
Purpose: No setup needed — this is a bug fix in an existing codebase with existing test infrastructure.
No tasks in this phase.
Phase 2: Foundational (Blocking Prerequisites)​
Purpose: No foundational work needed — all infrastructure exists.
No tasks in this phase.
Phase 3: User Story 1 — Active Audit Chat Survives Server Reload (Priority: P1) MVP​
Goal: Preserve the active conversation in loadConversationsFromServer regardless of message count, eliminating the race condition that causes the infinite "Loading conversation..." spinner for audit/shared conversations.
Independent Test: Open an audit conversation owned by another user, trigger a conversation list refresh, verify the conversation remains in the sidebar with messages intact.
Tests for User Story 1​
Write these tests FIRST, ensure they FAIL before implementation
-
T001 [US1] Add test
preserves active conversation not in server responsetoloadConversationsFromServer — deletion syncdescribe block inui/src/store/__tests__/chat-store.test.ts. SetactiveConversationIdto'audit-conv', add that conversation to local state with messages, mock server to return empty list. Assert'audit-conv'remains in store afterloadConversationsFromServer(). -
T002 [US1] Add test
preserves active conversation with zero messages (race condition)inui/src/store/__tests__/chat-store.test.ts. SetactiveConversationIdto'loading-conv', add that conversation with emptymessages: [](simulating messages still loading). Mock server to return empty list. Assert'loading-conv'remains in store after refresh. This validates FR-001's "regardless of whether messages have loaded yet" requirement. -
T003 [US1] Add test
no duplicate when active conversation is also in server responseinui/src/store/__tests__/chat-store.test.ts. SetactiveConversationIdto'both-conv', add that conversation locally, AND include it in the mock server response. Assert exactly 1 entry for'both-conv'in the store after refresh (from server, not duplicated by local-only preservation). -
T004 [US1] Update existing test
clears active conversation if it was deleted on another device(line ~1181) inui/src/store/__tests__/chat-store.test.ts. The test currently expectsactiveConversationIdto switch when the active conversation is not in the server response. With the fix, the active conversation should now be preserved as a local-only entry. Update assertions: the conversation should remain in the store andactiveConversationIdshould stay unchanged. Rename test topreserves active conversation even when absent from server response (audit/shared scenario).
Implementation for User Story 1​
-
T005 [US1] Modify the
localOnlyPreservedfilter inloadConversationsFromServerinui/src/store/chat-store.ts(~line 864-869). Remove&& conv.messages.length > 0from the active conversation condition. Change from(conv.id === currentState.activeConversationId && conv.messages.length > 0)to(conv.id === currentState.activeConversationId). -
T006 [US1] Update the
console.logat ~line 896 inui/src/store/chat-store.tsto accurately referencelocalOnlyPreservedand describe both preservation reasons (streaming and active audit/shared).
Checkpoint: Run make caipe-ui-tests — all new and updated tests for US1 should pass. The active conversation is preserved on refresh regardless of message count.
Phase 4: User Story 2 — Streaming Conversations Continue to Be Preserved (Priority: P1)​
Goal: Verify no regression in existing streaming conversation preservation behavior.
Independent Test: Start a new streaming conversation, trigger a refresh, verify the streaming conversation remains.
Verification for User Story 2​
-
T007 [US2] Verify existing test
preserves local-only conversations that are actively streaming(line ~1154) inui/src/store/__tests__/chat-store.test.tsstill passes after the changes from US1. No code changes expected — this is a regression check. Run the specific test to confirm. -
T008 [US2] Add test
does not preserve non-active non-streaming local-only conversationsinui/src/store/__tests__/chat-store.test.ts. Add a conversation that is NOT active and NOT streaming. Mock server to return empty list. Assert the conversation is removed from the store. This validates FR-004.
Checkpoint: Run make caipe-ui-tests — all streaming-related tests pass alongside the new active conversation tests.
Phase 5: Polish & Cross-Cutting Concerns​
Purpose: Final validation across both user stories
- T009 Run
make caipe-ui-teststo validate all chat-store tests pass (both new and existing) - T010 Run
make lintto ensure no linting issues introduced
Dependencies & Execution Order​
Phase Dependencies​
- Phase 3 (US1): No dependencies — can start immediately
- Phase 4 (US2): Depends on Phase 3 (US1) since both modify the same test file
- Phase 5 (Polish): Depends on Phase 3 + Phase 4
Within User Story 1​
- T001–T004 (tests) — write first, verify they fail
- T005–T006 (implementation) — make tests pass
- Checkpoint: all tests green
Within User Story 2​
- T007 (regression check) — verify existing test still passes
- T008 (new negative test) — verify non-preserved conversations are removed
Parallel Opportunities​
- T001, T002, T003 can be written in parallel (different test cases, same file — but logically independent)
- T005 and T006 are in the same file but different locations — can be done together in one edit pass
Implementation Strategy​
MVP First (User Story 1 Only)​
- Write tests T001–T004 → verify they fail
- Implement T005–T006 → verify tests pass
- STOP and VALIDATE:
make caipe-ui-tests - This alone fixes the core bug
Incremental Delivery​
- US1 (T001–T006) → Core fix, race condition eliminated
- US2 (T007–T008) → Regression safety net
- Polish (T009–T010) → Full validation
Notes​
- Total: 10 tasks (4 test tasks, 2 implementation tasks, 2 verification tasks, 2 validation tasks)
- All changes in 2 files:
chat-store.ts(production) andchat-store.test.ts(tests) - Production code change is ~3 lines (remove one condition, update one log message)
- The existing diff on the branch already has most of the fix — it just needs the
messages.length > 0check removed per the clarification