Observed defect
RefreshRecallRuntimeAsync() calls LoadRecallTimelineAsync(""); RenderRecallCardsAsync() clears the FlipView. Rebuild resets browsing to the newest entry even with automatic capture disabled.
Selection contract
Preserve identity, not index
- Add stable Recall entry ID to each carousel item/view-model or
FlipViewItem.Tag. - Before refresh, capture selected entry ID, numeric index as fallback, and whether the user is at newest.
- Reconcile items by ID; avoid rebuilding when IDs/content revisions are unchanged.
- If selected ID survives, restore it. If deleted, clamp the prior index to the new range; use
-1only when empty. - Background capture never steals navigation. Auto-select a new card only when the prior list was empty, the user explicitly enabled “Follow latest,” or a manual Capture now completed while the user was already at newest.
- Do not reload timeline on every status poll when
entry_countand query are unchanged.
Evidence views per card
| Tab | Canonical content | Notes |
|---|---|---|
| Image | Full frame + timestamp/model/status | Aspect-fit; caption overlay optional. |
| Extracted | Normalized caption, OCR, labels, confidence | Current summary becomes an explicit derived view. |
| Raw VLM | Exact provider response body/message content | Store bytes/text before normalization; redact no game text. |
| Review | Recall evidence agent output and validated actions | Separate from VLM; link run ID. |
| Trace | Review tool/reasoning activity when available | Links into trace inspector. |
Schema
entries: add analysis_id, capture_origin(manual|automatic), analysis_status recall_analyses: id, entry_id, provider, model, prompt_version, raw_response, normalized_json, created_at, latency_ms, error review_links: entry_id, local_run_id, review_status
Raw LM Studio/OpenAI responses may contain provider-specific fields. Save the complete JSON envelope plus a normalized projection. For Ollama, preserve both response and thinking if returned—even though current Recall requests set think:false.
Likely files
bridge/game_assist_bridge/recall.py— analyzer result envelope and migration.bridge/game_assist_bridge/commands.py— detail/raw endpoint; keep timeline payload compact.apps/windows-gamebar-widget/Widget1.Commands.cs— keyed reconciliation and detail tabs.apps/windows-gamebar-widget/Widget1.xaml— follow-latest toggle and Pivot/expander.tests/test_recall.py,tests/test_recall_commands.py,tests/test_windows_gamebar_widget.py.
Acceptance
- Browsing an older card survives ten status polls with automatic Recall on or off.
- A new automatic capture does not steal selection unless Follow latest is active.
- Raw VLM text is byte-for-byte attributable to provider/model/prompt version.
- Manual duplicate cards remain independently inspectable.
- Timeline list does not embed large raw payloads; details load on demand.