Salvage of PR #99679 by 686f6c61, rebased onto current main.
/new and idle/daily resets keep parent_session_id for durable lineage,
and the sidebar's flattenSessionsWithBranches nested on that field
alone — so a platform's chats collapsed into one growing nested chain
of branches even though none of them were /branch forks. The backend
records the distinction on disk already (model_config._reset_from vs
_branched_from, gateway/session_recovery.py:433) but list payloads
strip model_config before any UI can read it.
- forkParentId(): nest only genuine forks — _branched_from wins, a
_reset_from parent means top-level sibling, legacy/optimistic rows
with only parent_session_id keep nesting.
- _session_row_dict lifts _reset_from/_branched_from out of
model_config so compact list rows (which strip that heavy field)
carry the distinction; tui_gateway project-tree rows project the two
markers too.
- Optimistic desktop /branch rows stamp _branched_from so the flat
render stays correct before the authoritative row arrives.
Disk lineage is unchanged. Tests: a _reset_from chain renders flat,
a genuine fork still nests beside a reset sharing the same parent,
and list_sessions_rich promotes both markers (also under
compact_rows=True).
Closes#99648.