UXS-005: Semantic Search Panel¶
- Status: Active
- Authors: Podcast Scraper Team
- Parent UXS: UXS-001: GI/KG Viewer -- shared tokens, typography, layout, states
- Related PRDs:
- PRD-021: Semantic Corpus Search
- Related RFCs:
- RFC-061: Semantic Corpus Search
- RFC-062: GI/KG viewer v2
- RFC-072: Canonical identity + cross-layer bridge (chunk-to-Insight lift on transcript hits)
- RFC-075: Corpus Topic Clustering (optional Show on graph / cluster follow-ups)
- Implementation paths:
web/gi-kg-viewer/src/components/shell/LeftPanel.vue(hosts the search column)web/gi-kg-viewer/src/components/search/SearchPanel.vueweb/gi-kg-viewer/src/components/search/ResultCard.vueweb/gi-kg-viewer/src/components/search/SearchResultsVizDialog.vueweb/gi-kg-viewer/src/components/search/SemanticSearchTip.vueweb/gi-kg-viewer/src/stores/search.ts- Shell IA: VIEWER_IA.md — left panel Search + Explore, navigation axes, subject rail, status bar
Placement¶
Search is the default surface of the left query column; Explore is an alternate mode
(slide transition) entered via a quiet footer control (Explore corpus →) and exited via
← Search — see VIEWER_IA.md. Mode is shell.leftPanelSurface (search |
explore). / expands the column if needed, switches to Search, then focuses #search-q
(LeftPanel → focusQuery). LeftPanel.vue hosts SearchPanel.vue + ExplorePanel.vue
at w-72 when expanded. Search results stay visible when a hit opens in the subject rail
(mode switches do not clear the subject). Deprecated: right-rail-only search, episodeRail,
paneKind = tools as placement drivers.
Summary¶
For shell layout, the three navigation axes, subject rail persistence and clearing, status bar, and first-run empty corpus behavior, see VIEWER_IA.md. This document specifies the Search and Explore panel content only (query form, advanced filters, result cards, insights modal).
The semantic search panel provides FAISS-based corpus search in the left shell column
(Semantic search card: form + scrollable results; Explore corpus → sits in LeftPanel
below that card). This UXS defines the visual contract for the search form,
advanced filters, result cards, and the search result insights modal. All tokens reference
UXS-001.
Track shell work in GitHub #606 and RFC-062. When the viewer changes, update this Active UXS in the same PR — see Living documents and ship boundary.
RFC-075: When corpus clustering JSON is available, Show on graph from search still selects the
leaf node id (e.g. topic:…) as today. The graph node rail shows Topic cluster: for Topic
nodes (Phase 1; see UXS-004). Search result cards may show a
Topic cluster: line when the API joined metadata.topic_cluster (canonical label and compound
id). Show on graph may widen the camera to include the tc: compound parent while keeping
selection on the leaf. The pan/zoom animation and minimum zoom floor for that hand-off match
other graph focus paths (UXS-004 — Camera framing and selection).
Dashboard topic clusters: On the Dashboard → Intelligence sub-tab, the Topic clusters
status block reflects GET /api/corpus/topic-clusters
as soon as Corpus path is set and health is OK — you do not need to wait for GI/KG
artifacts to finish loading into the graph. While the request is in flight, Status shows Checking….
Then: Loaded, Not built (404 — optional
topic-clusters CLI), request error, or Local files only when the graph came from the file
picker (no API fetch for clustering). Unknown schema_version values get a non-blocking warning line.
Primary flow¶
Search query field (no separate label; placeholder + Semantic search heading) —
Enter submits the same as Search (disabled while loading / no corpus / API down);
Shift+Enter inserts a newline; IME composition does not trigger submit.
Then a filter chip bar (#671, data-testid="search-filter-bar") with four chips —
Since (search-chip-since, shared DateChip), Top‑k (search-chip-topk,
default 10), Doc types (search-chip-doctypes, empty = all), More
(search-chip-more, opens the slim Advanced search dialog). Each chip's label
switches from Label ▾ (default) to Label: detail ▾ when active; the More
chip shows More: N reflecting the count of non-default fields it hosts. Replaces
the legacy inline Since (date) + Top-k row, the "Advanced search" underline link,
and the read-only "Active advanced filters" summary block (which is gone — chip
labels carry the active state instead). Search / Clear sit below the chip
bar; scrollable results (errors + hit cards) follow in the middle.
Explore corpus → lives in LeftPanel.vue below the search card
(data-testid="left-panel-explore-footer" / left-panel-enter-explore)
so it stays visible above the status bar.
Advanced search dialog (slim, hosted by the More chip)¶
Opened by clicking the More filter chip; same backdrop pattern as before. After #671 the dialog hosts only the low-traffic fields that aren't worth a top-level chip:
- Feed (substring on catalog
feed_idfor the API; Library -> Prefill semantic search shows the feed title from the feeds catalog when known, with hover/title for the id until edited) - Grounded insights only
- Speaker contains
- Embedding model
- Merge duplicate KG surfaces (default on: same behavior family as graph
Entity/Topic dedupe for
kg_entity/kg_topicvector rows)
The legacy in-dialog Doc Types fieldset moved to the dedicated Doc types chip on the filter bar.
Search result insights¶
After at least one hit, an underlined Search result insights control opens a
modal (same backdrop pattern as Advanced search) titled "Search result insights" --
one scroll, no tabs: a short insight line (dominant doc type); Doc types and
Publish month in a two-column row (small multiples); Episodes / Feeds
with top rows (episode title / feed title from hit metadata, or loaded from the
episode's *.metadata.json when the index row omitted them) plus "+N other..." tail
counts; Similarity bars proportional to score / max(score) in the list
(captioned); Terms with a top-token insight (word frequency; heuristic, not KG).
Results¶
A muted "N results" / "1 result" line only (the query stays in the textarea; it is
not repeated here). When the API returns lift_stats and at least one transcript
row is on the page, a compact Lift: applied / transcript rows ratio appears on
the same row (native title explains RFC-072 lift coverage).
Each hit can expose:
- G (graph focus, GI token) and L (Library episode) as separate controls
- L requires a healthy API check + corpus path and
source_metadata_relative_pathon the hit (vector indexer stamps it on rebuild) corpus_library_apiin health can still be No while L shows; the Library tab surfaces errors if catalog routes are unavailable- E (episode id chip) is informational
- When Merge duplicate KG surfaces merged a row (
kg_surface_match_count>= 2), G only -- L and E are hidden so actions are not tied to a single representative episode - Transcript hits may include a collapsible
regionLifted GI insight (linked insight id/text, speaker/topic labels, quote time range) when the server attacheslifted(#528). Whenlifted.quotehas at least one finitetimestamp_*_msbutlifted.speakerhas no usable display label, a muted line shows the same visible copy as supporting quotes — No speaker detected (GI_QUOTE_SPEAKER_UNAVAILABLE_HINT; #541).data-testid="search-lifted-quote-speaker-unavailable". - Supporting quotes (Show / Hide N supporting quote(s)): when the API returns
supporting_quotesand a quote has nospeaker_name/speaker_id, a muted line shows No speaker detected (sameGI_QUOTE_SPEAKER_UNAVAILABLE_HINTas the graph Quote rail; #541).data-testid="supporting-quote-speaker-unavailable".
E2E contract¶
E2E surface map -- search panel surfaces and selectors.
Revision history¶
| Date | Change |
|---|---|
| 2026-04-21 | Query: Enter submits search; Shift+Enter newline; IME-safe. |
| 2026-04-21 | Explore CTA: LeftPanel footer below search card (clears status bar). |
| 2026-04-21 | Left column: Search default; Explore mode (slide); / restores Search + focus. |
| 2026-04-21 | Search: Since + Top-k row uses grid so fields stay in panel. |
| 2026-04-21 | Show on graph: UXS-004 camera + min zoom (cross-link). |
| 2026-04-06 | Initial content (in UXS-001) |
| 2026-04-13 | Extracted from UXS-001 into standalone UXS-005 |
| 2026-04-13 | Document lift_stats summary line + Lifted GI insight region |
| 2026-04-15 | Supporting quotes: muted hint when speaker missing (#541) |
| 2026-04-15 | Lifted GI: muted hint + testid when speaker display missing (#541) |
| 2026-04-15 | Lifted hint only when lifted.quote has finite timestamp_*_ms (matches E2E) |
| 2026-04-15 | #541: No speaker detected (graph + Search + Explore; semantics unchanged) |
| 2026-04-16 | Lifted GI: explicit same visible string as supporting quotes (No speaker detected) |
| 2026-04-19 | Shell IA: left query column copy; topic clusters card under Dashboard workspace (#606) |