The chat was a separate page — opening it left the summary behind, the very
context you're asking about. Now the chat docks open IN PLACE below the summary:
"Dig deeper" reveals the chat section (HTMX, outerHTML over the closed dock) so
the summary stays on screen above it; no navigation. The no-JS fallback renders
the full summary AND the open chat on one page (the same integrated view), so
progressive enhancement holds.
Extracts a shared summaryBody templ so the detail page and the chat page render
one identical summary, not two divergent ones. GET /v/{id}/chat returns just the
open chat section as a fragment for the inline reveal, or the full summary+chat
page for a no-JS navigation; POST swaps the panel inline or re-renders the whole
page. Tests assert summary+chat coexist on the page and the reveal is a fragment.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
70 lines
3.0 KiB
Gherkin
70 lines
3.0 KiB
Gherkin
Feature: Chat with a video's stored transcript
|
|
As a reader whose summary made me want to dig deeper
|
|
I want to ask questions about the video without watching it
|
|
So that I can go further on the ones worth it, without leaving the reader
|
|
|
|
# ADR-027. The load-bearing constraint is safety-by-construction: chat runs
|
|
# ONLY against an already-stored transcript (ADR-021) and never fetches captions,
|
|
# never touches the rate gate, never reaches YouTube. Entry is from the summary
|
|
# view of one's OWN video; the conversation is ephemeral (no persisted history).
|
|
|
|
Background:
|
|
Given I have a summarized video with a stored transcript
|
|
|
|
Scenario: A summary view offers a deeper-dive into the video
|
|
When I view the summary
|
|
Then I see a "dig deeper" affordance that opens a chat about this video
|
|
And it opens the chat in place, below the summary, without leaving the page
|
|
|
|
Scenario: The summary and the chat are on one page
|
|
When I open the chat
|
|
Then the summary stays visible alongside the chat
|
|
And I can read the summary while I ask questions
|
|
|
|
Scenario: Ask a question answered from the stored transcript
|
|
When I ask a question in the chat
|
|
Then the answer is produced from the stored transcript
|
|
And no caption fetch and no YouTube call occurs
|
|
|
|
Scenario: Chat never fetches captions or reaches YouTube
|
|
When I ask a question in the chat
|
|
Then Tapir reads only the stored transcript
|
|
And the caption-fetch and video-fetch paths are never invoked
|
|
|
|
Scenario: A video with no stored transcript offers no chat
|
|
Given a video that has no stored transcript
|
|
When I open the chat for it
|
|
Then I am told chat is not available
|
|
And no fetch is attempted and no model is called
|
|
|
|
Scenario: The default model is the summary's model and is switchable
|
|
When I open the chat
|
|
Then the model defaults to the model that produced the summary
|
|
And I can switch among the offered chain models
|
|
|
|
Scenario: Switching models re-runs against the same transcript
|
|
When I ask a question with a different chain model selected
|
|
Then the chosen model answers
|
|
And it answers against the same stored transcript
|
|
|
|
Scenario: The cloud model is hidden when cloud is disabled
|
|
Given the cloud fallback model is disabled
|
|
Then the chat switcher offers only local models
|
|
|
|
Scenario: A long transcript is bounded and the chat says so
|
|
Given the stored transcript is longer than the model budget
|
|
When I ask a question
|
|
Then the answer is produced from a bounded portion
|
|
And the chat notes that it worked from a bounded portion
|
|
|
|
Scenario: A multi-turn conversation is ephemeral
|
|
When I ask a follow-up question
|
|
Then the prior turn is carried into the answer
|
|
And nothing about the conversation is written to the database
|
|
|
|
Scenario: Chat is reachable only from my own summary view
|
|
Given another user has a summarized video with a stored transcript
|
|
When I try to open the chat for their video
|
|
Then I get a not-found response
|
|
And no model is called
|