Files
brain-of-reese/.agent/user_stories/chat-persistence.md
T
ducoterra 4971e2859d
Build and Push Containers / build-and-push-app (push) Successful in 12s
Build and Push Containers / build-and-push-db (push) Successful in 10s
chore(agent): track .agent/ planning tree in git
Remove the blanket .agent/ gitignore so the phase roadmap, user
stories, reports, and PLAN.md are versioned with the code. Only
runtime artifacts (.agent/phase-sessions/, .agent/pipeline.log)
remain ignored. Update AGENTS.md git protocol rule to match.
2026-09-01 10:18:22 -04:00

2.1 KiB

Story: Chat Survives a Refresh (localStorage)

Phase: 14_chat_persistence.md · E2E: tests/e2e/test_chat_persistence.py

Narrative

As a user, I want my conversation to survive a browser refresh and a trip to another page — the previous session should be waiting for me when I come back.

  • Given I have asked a few questions
  • When I refresh the page (or go to Sources and come back)
  • Then the whole conversation is restored: my questions, Brain's answers (rendered markdown), the source chips, and deflected answers with their "Maybe try" chips — amber style included.

Acceptance criteria

  1. Conversation state (user + brain messages, with sources/deflection/ suggestions metadata) is stored in localStorage under a versioned key; user messages are saved when sent, brain answers when the turn completes.
  2. On load, stored messages are re-rendered (markdown, source chips, deflected styling + maybe-try chips); the empty state is hidden when a conversation exists.
  3. "New chat" control (chat header) clears the stored conversation and returns to the empty state with suggestions.
  4. Storage failures (private mode / quota) degrade silently — chat still works, nothing throws.
  5. Size-bounded: oldest messages are dropped if the serialized conversation outgrows the quota budget.
  6. Unit + integration green, app/ coverage >90%, story E2E green in isolation, one --no-gpg-sign commit.

Playwright Mapping Rule

Test Scenario → tests/e2e/test_chat_persistence.py (mock LLM, seeded KB):

  1. test_conversation_survives_reload — ask → answer with source chip → page.reload() → both bubbles restored (text + chip href), empty state hidden.
  2. test_deflected_turn_restores_styling — off-topic question → deflected answer → reload → amber bubble + "Maybe try" chips back.
  3. test_new_chat_clears_conversation — with a conversation, "New chat" → messages gone, empty state + suggestions back, storage key cleared.
  4. test_persists_across_page_navigation — ask → go to Sources → back to / → conversation still there.