# Session Timeline Consistency Design

## Problem

CTM has several surfaces that describe the same provider session:

- the sidebar/status tooltip,
- the Conversation tab,
- the prompt menu,
- Review and mobile live history.

Historically these surfaces used different read paths. The tooltip/status card
reads a hot `SessionCapture` / `SessionStream` summary, while Conversation and
prompt menus read durable message caches and then optionally layer stream
events on top. That split lets the tooltip show the newest prompt while the
Conversation tab still shows an older imported transcript.

## Non-Regression Contract

The fix must not make realtime surfaces slower.

- Hot status/tooltip summaries stay hot-first. They must not block on large
  transcript parsing, DB imports, or pagination.
- Conversation and prompt metadata must include the same recent hot stream tail
  that the summary sees.
- Durable caches remain the source for historical transcript pages.
- When a CTM tab id and provider agent id differ, every consumer must resolve
  the same identity set before reading stream or durable state.

## Source Layers

The canonical timeline is a layered composition, not a single table:

1. **Hot stream ring**: immediate user/assistant events from live provider
   sessions. This wins for latest prompt/progress while a session is running.
2. **Warm DB/index cache**: imported conversation rows and message index. This
   wins for historical transcript reads.
3. **Cold transcript files**: JSONL/rollout parsing used for backfill and
   repair. It must not slow hovercards or active prompt metadata.

The shared identity resolver expands a requested id into:

- requested id,
- canonical CTM tab id when known,
- provider agent session ids linked to the CTM tab,
- conversation source ids used by the durable cache,
- stream lookup ids used by hot-tail readers.

## Merge Rules

- Query hot stream events for every resolved stream lookup id.
- Deduplicate stream events by event id when available, otherwise by
  role/timestamp/text.
- Merge durable messages plus hot events with `mergeMessagesWithStreamEvents`.
- Return freshness metadata for structured responses:
  - `source`,
  - `streamTailAdded`,
  - `timelineIdentity`,
  - `timelineFreshness`.
- Prompt metadata uses the same stream lookup function as Conversation.
- Summary/card metadata uses real user-turn timestamps before preview columns;
  preview columns are fallback only.

## Session Insight Contract

Tooltip cards, Overview cards, and Conversation must describe one shared session
state. They can render different amounts of detail, but they must not choose
different "latest prompt" sources.

The canonical projection is:

- `latestAsk`: the newest meaningful user prompt from real message turns or hot
  stream events.
- `currentState`: status/progress derived from hot stream, assistant events,
  approval state, and worktree signals.
- `aiBrief`: an optional compression over `latestAsk` plus recent evidence. It
  is display help, not the source of truth.
- `evidence`: compact source labels used to explain why a card says running,
  waiting, stale, dirty, or reviewable.

`last_user_content` and related preview columns are title/search accelerators.
They are valid only when no real user turn is available from messages, message
index, or hot stream tail. They must never outrank a real user turn merely
because the cache row was imported later.

AI freshness is tied to the same prompt ledger used by `latestAsk`. A summary is
fresh only when its prompt fingerprint covers the canonical latest prompt.

## Rollout Plan

Phase 1 keeps the status card route hot-first and moves Conversation/prompt
tail lookup onto the shared identity resolver. This fixes stale Conversation
tails without making status summaries wait for DB/file work.

Phase 2 can make `/api/sessions/:id/summary` consume a small, hot-first
timeline summary object, but only after tests prove the endpoint never falls
through to cold parsing on the hover path.

## Required Tests

- CTM id with multiple provider agent ids returns hot events from linked agent
  ids, not just the requested CTM id.
- Conversation merge appends the newest stream prompt while preserving cached
  history.
- Prompt menu/version sees the same stream tail as Conversation.
- Tooltip/status summary still resolves from the hot stream path and does not
  require a durable cache row.
