Note
Grok responding on behalf of Julius.
Triage
Thanks @yaacovcorcos for the thorough cause analysis, it lined up closely with what I found in the code.
What I found
- This reproduces from the code on current
main. A pull request's linked-thread list includes archived threads (listLinkedPullRequestThreadsdoesn't filterarchived_at); the command palette labels them "Archived thread" and navigates to/$environmentId/$threadId(buildLinkedThreadActionItems). The lineage panel merges the archive snapshot into the relationship graph and opens the same route, and pasting the URL hits the same view. - The live shell only keeps active threads:
environmentThreadsAtomreadssnapshot.threads, and archiving publishesthread.removedon the active shell stream, souseThreadShellis null. After bootstrap,resolveThreadRouteRenderStateturns that intomissing,ThreadRouteViewnever mountsChatView, and the URL is replaced with/(or the inset stays empty if there's no other thread). - The server can still load it:
getThreadSnapshotlooks the row up by id without filteringarchivedAt, and a real miss returns 404, which the client stores asdeleted. - Mounting
ChatViewalone wouldn't be enough, since its active thread is the same shell and!activeThreadrendersNoActiveThreadState. - Mobile already handles this case: when the active shell is missing,
useResolvedThreadSelectionloads the thread detail and builds a local shell withthreadDetailToShell, andThreadRouteScreenstays loading until that shell exists.
Likely fix area
Some options for the shell source you flagged:
- Mirror mobile: keep the route loading until the detail resolves, build a local shell from the loaded projection, mount the chat, and leave the route only when the detail is
deleted. Keeping that shell local (rather than inserting it into the live shell list) would avoid the archived thread showing up in the sidebar and palette. - Use the archive shell snapshot (
orchestrationEnvironment.archivedShellSnapshot). Note it's a separate list and can lag the live shell.
Either way, message.dispatch already rejects archived threads as not active, so the composer would need to stay disabled (or offer unarchive) when archivedAt is set. Desktop is affected too, since it wraps the web client.
A maintainer will decide on the fix direction.