refactor(agents): migrate .agent/ planning tree to .agents/
Standardize on the .agents/ directory (shared with project skills): phases/, user_stories/, reports/, screenshots/, validate.sh, and phase-sessions/ + pipeline.log all move to .agents/ (git mv preserves history; runtime artifacts move alongside). Updates every reference in AGENTS.md, README.md, .gitignore, app docstrings, and test story headers. Historical KB content in data/ and the runtime pipeline.log transcript are left untouched.
This commit is contained in:
@@ -0,0 +1,45 @@
|
||||
# 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.
|
||||
Reference in New Issue
Block a user