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.
2.1 KiB
2.1 KiB
Story: Document Back Button Returns to Where You Came From
Phase: 13_document_back_navigation.md · E2E: tests/e2e/test_document_back_navigation.py
Narrative
As a user, when I open a document from the chat tab (a source chip), the viewer's back button must take me back to the chat — not to Sources. When I open it from Sources, it takes me to Sources.
Today every chip/link opens the viewer in a new tab, where there is
no browser history, so the fallback always lands on /sources.html —
which is wrong for chat-originated visits.
- Given I open a document from chat (chip) or from Sources (table)
- When I click the viewer's back button
- Then I land on the page I opened it from — Chat or Sources.
Acceptance criteria
- Chat source chips carry
&back=%2F(chat) in the viewer URL; Sources table links keep the default (nobackparam →/sources.html). - The viewer resolves the back target:
backparam wins when it is a same-origin relative URL (starts with/, not//); anything else (missing, absolute, protocol-relative, garbage) falls back to/sources.html. The back link's label matches (Chat / Sources). - Clicking back navigates to the resolved target (deterministic — no
history.lengthheuristics). - Phase-10 viewer behavior and a11y frame unchanged.
- Unit + integration green,
app/coverage >90%, story E2E green in isolation, one--no-gpg-signcommit.
Playwright Mapping Rule
Test Scenario → tests/e2e/test_document_back_navigation.py (seeded KB):
test_back_from_chat_returns_to_chat— question → click source chip → new tab at/document.html?…&back=%2F→ back link href is/and labeled "Chat" → click → URL is the chat page.test_back_from_sources_returns_to_sources— Sources → click path link → new tab (nobackparam) → back link href is/sources.html, labeled "Sources" → click → URL is Sources.test_malicious_back_param_is_rejected—back=https%3A%2F%2Fevil.comandback=%2F%2Fevil.com→ back link falls back to/sources.html.