Treat first rollout session_meta as canonical thread identity (#11241)

During thread/fork, the new rollout includes the fork’s own session_meta
plus copied history that can contain older session_meta entries from the
source thread. thread/list was overwriting metadata on later
session_meta lines, so a fork could be reported with the source thread’s
thread_id. This fix only uses the first session_meta, so the fork keeps
its own ID.
This commit is contained in:
guinness-oai 2026-02-10 10:32:11 -08:00 committed by GitHub
parent a364dd8b56
commit 099ed802b2
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 22 additions and 19 deletions

View file

@ -1015,25 +1015,27 @@ async fn read_head_summary(path: &Path, head_limit: usize) -> io::Result<HeadTai
match rollout_line.item {
RolloutItem::SessionMeta(session_meta_line) => {
summary.source = Some(session_meta_line.meta.source.clone());
summary.model_provider = session_meta_line.meta.model_provider.clone();
summary.thread_id = Some(session_meta_line.meta.id);
summary.cwd = Some(session_meta_line.meta.cwd.clone());
summary.git_branch = session_meta_line
.git
.as_ref()
.and_then(|git| git.branch.clone());
summary.git_sha = session_meta_line
.git
.as_ref()
.and_then(|git| git.commit_hash.clone());
summary.git_origin_url = session_meta_line
.git
.as_ref()
.and_then(|git| git.repository_url.clone());
summary.cli_version = Some(session_meta_line.meta.cli_version);
summary.created_at = Some(session_meta_line.meta.timestamp.clone());
summary.saw_session_meta = true;
if !summary.saw_session_meta {
summary.source = Some(session_meta_line.meta.source.clone());
summary.model_provider = session_meta_line.meta.model_provider.clone();
summary.thread_id = Some(session_meta_line.meta.id);
summary.cwd = Some(session_meta_line.meta.cwd.clone());
summary.git_branch = session_meta_line
.git
.as_ref()
.and_then(|git| git.branch.clone());
summary.git_sha = session_meta_line
.git
.as_ref()
.and_then(|git| git.commit_hash.clone());
summary.git_origin_url = session_meta_line
.git
.as_ref()
.and_then(|git| git.repository_url.clone());
summary.cli_version = Some(session_meta_line.meta.cli_version);
summary.created_at = Some(session_meta_line.meta.timestamp.clone());
summary.saw_session_meta = true;
}
}
RolloutItem::ResponseItem(_) => {
summary.created_at = summary

View file

@ -881,6 +881,7 @@ async fn test_list_threads_scans_past_head_for_user_event() {
.unwrap();
assert_eq!(page.items.len(), 1);
assert_eq!(page.items[0].thread_id, Some(thread_id_from_uuid(uuid)));
}
#[tokio::test]