Files
brain-of-reese/.agent/user_stories/summary-in-viewer.md
T

2.0 KiB

Story: Summary + Original Document Together in the Viewer

Phase: 36_summary_in_viewer · E2E: tests/e2e/test_summary_in_viewer.py

Narrative

As any user, phase 30 gives every non-markdown document a lite-model summary (stored on documents.summary, indexed as an is_summary chunk, used for retrieval). When I open such a document — from the Sources table, a chat source chip, or a direct URL — I only see the raw original. I want to see the summary and the original document together.

  • Given a document that has a summary (phase 30: non-markdown A9 documents)
  • When I open it in the document viewer (the modal or the full page)
  • Then a labeled Summary panel sits above the original content — both visible at once. Documents without a summary (markdown docs, pre-phase-30 rows, fail-soft rows) render exactly as before.

Acceptance criteria

  1. DocContent gains summary: str | None; GET /api/documents/content returns documents.summary. The endpoint stays public + stateless — the phase 16 soft rule (catalog gated, viewer public) is unchanged.
  2. The shared renderer renderDocument (assets/document.js) renders the summary panel for both surfaces at once (the full-page viewer + the chat/sources modal); null/empty summary → no panel; the summary text is written with textContent (XSS contract unchanged).
  3. .doc-summary styling matches the dark tech theme (phase 08 palette, contrast ≥4.5:1) and reads as a summary, not as document content.
  4. Integration tests: a summarized non-markdown doc returns its summary; a markdown doc returns null; anonymous access unchanged.
  5. Story E2E green in isolation (the summary_kb fixture: the deterministic digest panel + the full original with its tail sentinel visible together; the markdown control doc → no panel); regressions green; app/ coverage >90%; ruff + pyright clean; one --no-gpg-sign commit.

Playwright Mapping Rule

tests/e2e/test_summary_in_viewer.py — one story, one file, run in isolation.