UXS-009: Position Tracker¶
- Status: Draft
- Authors: Marko
- Parent UXS: UXS-001: GI/KG Viewer -- shared tokens, typography, layout, states
- Related PRDs:
- PRD-028: Position Tracker -- full requirements and API contract
- Related RFCs:
- RFC-072: Canonical Identity Layer -- bridge artifact, Flagship 1, query Pattern A
- RFC-062: GI/KG viewer v2
- Related UX specs:
- UXS-004: Graph Exploration -- "View in graph" handoff
- UXS-005: Semantic Search -- search entry point for speaker click
- UXS-007: Topic Entity View -- cross-linked from topic selector
- UXS-008: Enriched Search -- enriched search entry point; speaker names in enriched sources can open Person Landing
- UXS-010: Person Profile -- "Open profile" handoff; owns the shared Person Landing that hosts both Person Profile and Position Tracker
- Implementation paths:
- New:
web/gi-kg-viewer/src/components/person/PositionTracker.vue - Existing:
web/gi-kg-viewer/src/components/graph/GraphNodeRailPanel.vue(rail host) - Existing:
web/gi-kg-viewer/src/stores/(newperson.tsstore or extend existing) - Shell IA: VIEWER_IA.md — Person subject in subject rail; navigation axes
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 Position Tracker within Person Landing / the subject rail only.
The Position Tracker is a person + topic navigable surface that shows how a person's stated positions on a topic evolve across episodes. This UXS defines the visual contract for the panel layout, timeline cards, Insight and Quote card components, topic selector, and graceful degradation states. All tokens reference UXS-001. Functional requirements are in PRD-028.
Principles¶
- Chronological narrative: The primary axis is time. The user reads the arc top to bottom (most recent first) and sees how positions evolved.
- Grounding-first: Every Insight is accompanied by its verbatim quote. The quote is the evidence; the Insight is the interpretation.
- Honest degradation: When data is missing, the panel says so in plain language. No broken layouts, no spinners that never resolve.
Scope¶
In scope:
- Position Tracker right rail panel (graph and search entry points)
- Position Tracker full-width layout when Person Landing runs in the main column (browse host undecided; see UXS-010 — Full-width browse)
- Person header, topic selector, insight type filter
- Episode timeline with Insight and Quote cards
- All five degradation states (FR3.1 -- FR3.5)
Non-goals:
- Audio playback from timestamps (display only)
- Cross-corpus person views
Boundary note: This UXS covers the static visual contract (tokens, layout, component appearance, accessibility targets). Behavioral rules (animation timing, debounce intervals, data-fetching strategies) belong in the related RFC. See the UXS vs RFC boundary guidance.
Theme support¶
- Mode: both (follows system)
- Primary palette: dark -- the mode used as the design baseline
- Breakpoints: desktop only (right rail minimum width 360px)
Placement¶
The Position Tracker panel has two presentation modes:
- Right rail (from graph or search entry point): same panel slot used for graph node detail and episode detail. Panel width follows the existing rail width (UXS-001).
- Full-width (only once browse ships; same shell gap as UXS-010): occupies the main content area. Layout is the same vertical stack but with wider cards and more horizontal space for Insight text.
The panel header shows "Position Tracker" with the gi domain token color, reflecting
that the primary data source is GIL Insights.
Entry points¶
The Position Tracker lives within the shared Person Landing component (owned by UXS-010). All entry points navigate to the Person Landing, which defaults to the Person Profile tab. The user toggles to the Position Tracker from there. When the entry point is topic-specific, the Position Tracker tab is preselected with that topic active.
- Clicking a Person node in the Cytoscape graph opens the Person Landing in the right rail.
- Clicking a speaker name in a search result card (including lifted results with
lifted.speakeror enriched sources from UXS-008) opens the Person Landing in the right rail.
Full-width (planned): There is no implemented top-level browse control in the v2 main tabs (Digest | Library | Graph | Dashboard). Full-width Position Tracker is the same Person Landing container as the rail case; where corpus-wide browse lives is specified under UXS-010 — Full-width browse. Until that ships, validation and E2E should assume rail entry only.
Section layout¶
The panel is a single scrollable column on surface background. Sections stack
vertically with border dividers between them.
Person header¶
- Person display name (
text-lg font-semibold) and canonicalperson:{slug}ID (muted,text-xs, monospace). - Appearance count badge (
surfacechip,text-sm): "N episodes". - Date range (first and last appearance) in
mutedtext-xs.
Action buttons¶
Below the header, a row of action buttons:
- View in graph -- navigates to the Graph tab and focuses on this person's node.
Uses
primarytoken. - Open profile -- navigates to the Person Profile (PRD-029) for this person.
Uses
primarytoken.
Topic selector¶
- A searchable dropdown (
surfacebackground,border,text-sm) populated from the person's known topics with display names. - Placeholder text: "Select a topic to see position arc..."
- A "View topic" link (
linktoken,text-xs) next to the selected topic navigates to the PRD-026 Topic Entity View. - When the person has no topics: the dropdown is disabled with
disabledtext, "No topics found."
Insight type filter¶
- A segmented control (
surfacebackground,border) with three options: - "Claims" (default, selected state uses
primaryfill) - "Recommendations"
- "All"
- Compact:
text-xs, fits on one line next to the topic selector in full-width mode, or below it in right rail mode.
Episode timeline¶
- Episodes are displayed as cards in a vertical stack, ordered by
publish_date(most recent first). - A thin connecting line (
bordertoken, 2px) runs vertically between cards on the left edge, creating the timeline metaphor. - Each episode card:
surfacebackground,borderborder, rounded corners (UXS-001 radius).- Episode title (
text-sm font-medium), podcast title (muted,text-xs), publish date (muted,text-xs). - Insight count badge: "N insights" (
surfacechip,text-xs).
Insight cards¶
Insight cards follow the shared InsightCard contract in
UXS-001 — InsightCard (shared component).
This view uses the following InsightCard slots: insight text, insight_type badge,
position_hint bar, confidence score, grounding badge. Episode attribution is
provided by the parent episode card context.
Within each episode card, Insights are listed vertically, ordered by position_hint
ascending (early in episode first).
- Insight text (
text-sm,canvas-foreground). insight_typebadge: small pill (text-xs).- "claim" ->
primarytoken. - "recommendation" ->
successtoken. - "observation" ->
mutedtoken. - "question" ->
linktoken. - Other/unknown ->
mutedtoken. position_hintindicator: a small horizontal bar (40px wide, 4px tall) filled proportionally. Usesprimarytoken fill onborderbackground. Tooltip: Never show the raw 0.0–1.0 float. If episodeduration_msis available, computeposition_hint × duration_msand show~[M]m [S]s into episode. If duration is unavailable, show a tier label: 0.0–0.33 → "Early in episode"; 0.34–0.66 → "Mid episode"; 0.67–1.0 → "Late in episode".- Confidence score:
mutedtext-xs, e.g. "0.88 confidence". Hidden when not available. - Grounding badge: "grounded" (
successtoken,text-xs) or "ungrounded" (warningtoken,text-xs).
Quote cards¶
Within each Insight, supporting quotes are listed:
- Blockquote style:
borderleft border (3px),surfacebackground with slight indent (padding-left 12px). - Quote text (
text-sm, italic,canvas-foreground). - Timestamp display (
muted,text-xs): formatted as "MM:SS -- MM:SS" fromtimestamp_start_msandtimestamp_end_ms. When timestamps are unavailable, hidden entirely (no "unknown" placeholder). - Episode attribution (
muted,text-xs): shown only when the quote is displayed outside its episode context (e.g. in a future cross-reference view).
Graceful degradation¶
All degradation states use muted text and honest language. No broken layouts.
- Person has 0 Insights (FR3.1): Person header shows with KG metadata. Topic
selector is empty/disabled. Arc area shows: "No grounded insights found for this
person. Insights appear when the pipeline runs with GIL extraction enabled."
(
muted,text-sm, centered in arc area). - Person has Insights but 0 grounded Quotes (FR3.2): Insight cards display with
"ungrounded" badge. Quote section within each Insight is hidden. A note below the
Insights: "These insights are not grounded in verbatim quotes. Grounding improves
with diarization and GIL extraction quality." (
muted,text-xs). - Selected topic has 0 Insights (FR3.3): Topic appears in selector. Arc area
shows: "No insights on this topic for [person name]. Try selecting a different
topic or viewing all types." (
muted,text-sm, centered). - Lift fails (FR3.4): Search result card shows raw chunk without speaker link. No Position Tracker navigation offered. (This state is in the search panel, not the Position Tracker panel itself.)
- No bridge.json for all episodes (FR3.5): Arc area shows: "No cross-layer data
available. Run the pipeline with bridge generation enabled." (
muted,text-sm, centered). Person header still shows KG-derived metadata if available.
E2E contract¶
New visible labels and selectors require updates to the E2E surface map before or with implementation. Key surfaces:
- Right rail panel with
aria-label="Position Tracker"(useexact: true) - Full-width Person Landing host (after browse placement is chosen and built)
- Person header (display name, appearance count)
- Topic selector dropdown
- Insight type filter segmented control
- Episode timeline cards
- Insight cards with type badges and grounding badges
- Quote blockquotes with timestamps
- "View in graph" and "Open profile" buttons
- All five degradation empty states
Accessibility¶
- Focus: Visible focus ring on all interactive elements (topic selector, filter,
buttons, episode cards). Uses
primarytoken, 2px solid, 2px offset. - Contrast: WCAG AA for all text on
surfacebackgrounds. Badge text meets contrast requirements against badge backgrounds. - Keyboard: Topic selector is keyboard-navigable (arrow keys, Enter to select). Episode cards are focusable for screen reader navigation.
- Screen reader: Episode cards use
role="article"witharia-labelincluding episode title and date. Insight type badges usearia-labelfor the full type name.
Revision history¶
| Date | Change |
|---|---|
| 2026-04-13 | Initial draft (PRD-028 companion) |
| 2026-04-19 | InsightCard links: UXS-001 subsection anchor |
| 2026-04-19 | Full-width TBD; rail-only; see UXS-010 browse note |