feat(site/src): reconcile chats-by-workspace cache across archive and watch paths by DanielleMaywood · Pull Request #27901 · coder/coder · GitHub
Skip to content

feat(site/src): reconcile chats-by-workspace cache across archive and watch paths - #27901

Merged
DanielleMaywood merged 2 commits into
feat/chat-search-invalidationfrom
feat/by-workspace-reconciliation
Aug 6, 2026
Merged

feat(site/src): reconcile chats-by-workspace cache across archive and watch paths#27901
DanielleMaywood merged 2 commits into
feat/chat-search-invalidationfrom
feat/by-workspace-reconciliation

Conversation

@DanielleMaywood

Copy link
Copy Markdown
Contributor

Implements Phase 2 item 5 of the chats query architecture: by-workspace cache reconciliation. Stacked on #27892; base branch feat/chat-search-invalidation.

Problem

chatsByWorkspace mappings (flat Record<workspaceId, chatId>, IDs only, archived chats filtered server-side) go stale on archive/unarchive, workspace binding changes, and watch events (FINDINGS 2.3). Because the client cannot re-derive archived state from the cached map, the only correct repair for a stale mapping is synchronous removal plus family invalidation.

Fix

  • New removeChatFromChatsByWorkspace(queryClient, chatId) in site/src/api/queries/chats.ts: value-match removal across the by-workspace family, reference-preserving when nothing is removed (mirrors the patchChatMessages no-op pattern).
  • archiveChat.onSuccess and the AgentsPageLayout archive-and-delete onSuccess synchronously remove the mapping; the existing onSettled/explicit invalidations then reconverge.
  • Watch handler: deleted branch removes then invalidates (remove-before-invalidate ordering); created root branch invalidates; merge path invalidates behind a new shouldInvalidateChatsByWorkspace predicate (status_change, action_required only; created/deleted have their own branches, title/summary/diff/context events do not move updated_at ordering); onOpen reconnect invalidates for convergence.
  • useChatToolInvalidations: workspace-binding tool completion (create_workspace) also invalidates by-workspace; this is the only reconciliation path on the embed route.

Confirmed exclusions

  • No optimistic patch in updateChatWorkspace.onMutate; the awaited onSettled invalidation already converges.
  • No cancellation guard for the by-workspace family (Phase 2 item 9 territory).
  • No createChat change (already invalidates); no ACL or pin changes.

Known constraints

  • Cascade archives remove only the event's own chat ID from the mapping; per-family-member deleted events plus family invalidation repair the rest.
  • The REST patchChat workspace-rebind branch publishes no watch event server-side, so cross-session manual rebinds converge only via the acting session's onSettled or a WorkspacesPage remount; not fixable client-side.

Testing

  • chats.test.ts: removal scoping and reference-preservation tests; it.each wiring tests (archiveChat/unarchiveChat/updateChatWorkspace onSettled, createChat onSuccess invalidate by-workspace); synchronous-removal assertion for archiveChat.onSuccess; negative assertions for updateChatTitle and createChatMessage.
  • AgentsPageLayout.test.ts: exhaustive ChatWatchEventKind table for shouldInvalidateChatsByWorkspace.
  • useChatToolInvalidations.test.tsx: create_workspace regression test extended with a seeded by-workspace bystander.

PR generated by Coder Agents.

@DanielleMaywood

Copy link
Copy Markdown
Contributor Author

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Nice work!

Reviewed commit: e7b7c15287

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@DanielleMaywood
DanielleMaywood force-pushed the feat/by-workspace-reconciliation branch from e7b7c15 to ab5794a Compare August 6, 2026 08:23
@DanielleMaywood
DanielleMaywood force-pushed the feat/by-workspace-reconciliation branch from ab5794a to 9474956 Compare August 6, 2026 08:47
@DanielleMaywood
DanielleMaywood marked this pull request as ready for review August 6, 2026 09:02
Comment thread site/src/api/queries/chats.ts Outdated

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

kinda long

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shortened in 4a7cea4. The production comment is now one line stating the Set purpose, and the near-duplicate rationale moved into the exhaustive-kind test comment (created/deleted have their own watch branches; title/summary/diff/context do not move updated_at ordering). Net 6 lines removed.

Reply generated by Coder Agents.

@DanielleMaywood
DanielleMaywood merged commit f9047e5 into main Aug 6, 2026
26 checks passed
@DanielleMaywood
DanielleMaywood deleted the feat/by-workspace-reconciliation branch August 6, 2026 09:25
@github-actions github-actions Bot locked and limited conversation to collaborators Aug 6, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants