Skip to content

fix(desktop): search workspace stores before the global root in known_session_roots - #760

Open
tonyfettes wants to merge 4 commits into
mainfrom
haoxiang/fix-known-session-roots-order
Open

fix(desktop): search workspace stores before the global root in known_session_roots#760
tonyfettes wants to merge 4 commits into
mainfrom
haoxiang/fix-known-session-roots-order

Conversation

@tonyfettes

Copy link
Copy Markdown
Contributor

Summary

known_session_roots was ordering stores as (1) global root, (2) workspace stores — the reverse of the old session_store_root priority (which searched workspaces first, then fell back to global). This meant that if the same session id existed in both, live_record_root and archived_record_root would return the global record instead of the workspace record the sidebar row was targeting.

This PR swaps the order: workspace stores first, then global root as fallback — matching the old behavior.

Why not a bigger change

The Codex review on #758 suggested passing workspace identity through the frontend message. That would add complexity to the ArchiveSession message schema and every call site, while the real fix is just reordering one array — the client hint is deliberately not trusted (the comment on live_record_root explains why), so the search order is all you need.

Practical impact

Session ID collisions across stores are near-impossible in practice (fingerprint entropy), so this is correctness work, not a bugfix for a user-facing issue. But the old ordering was clearly wrong and costs nothing to correct.

Stacked on #758.

tonyfettes and others added 4 commits August 10, 2026 01:34
…usals

Archiving resolved its record through the registered-workspace mapping
alone, so a conversation whose workspace had just been detached (or whose
directory vanished) fell back to the global store and failed with a bare
"no durable record for this conversation" — while the sidebar, which had
missed the registry change, kept offering both the workspace and the
conversation, and every retry failed identically.

- archive_session_commit now searches every known store root for the live
  record (mirroring the archived-twin lookup), names an already-archived
  record as exactly that, and scopes the not-found refusal to what was
  actually searched.
- EngineError derives Debug: proton logs failed handlers through Repr,
  which rendered the error as an opaque `<...EngineError: ...>` and
  swallowed the one string saying what failed.
- The frontend answers a definitive archive refusal by re-adopting the
  workspace registry snapshot and refreshing the archived list, so a page
  that missed workspace.changed converges instead of staying wedged on
  rows the host no longer serves.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
A transcript load for a conversation whose workspace just detached fell
through to the global store and surfaced the engine's raw file error
("@fs.open(): ... No such file or directory"). Check the record's
existence before spending the engine read, and answer with the same
actionable refusals archive now uses: archived records say "unarchive it
first", unreachable ones name the searched scope.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Every icon was raw codicon markup injected via Attrs::inner_html. An
innerHTML-bearing element cannot be safely morphed by rabbita's positional
child diff: assigning the property silently drops the real children the
runtime still tracks, and the next child-list shift that lines a text span
up with an icon span crashes the diff (and with it, rendering — the
workspace-detach freeze). Transcribe all 33 icons into @svg element
builders — path data unchanged, verified verbatim against the previous
markup — so no innerHTML remains in the frontend and the hazard is gone
regardless of the rabbita version in use. Icons become functions rather
than shared constants, so no Props instance is aliased between mounts.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…_session_roots

Restore the old `session_store_root` priority: when the same session id
exists in both a workspace store and the global store, find the workspace
record first. The previous ordering (global first, workspaces after)
could return the wrong record during archive/unarchive — unlikely to
matter in practice (session id entropy makes collisions near-impossible),
but correct and costs nothing.

Also updates the doc comment to explain the ordering.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 596bc221e0

ℹ️ 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".

Comment on lines 31 to +35
for path in registered_workspaces() {
roots.push(workspace_session_root(path))
}
if resolved_session_root() is Some(root) {
roots.push(root)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Carry the selected store through archive requests

When the same session ID exists in both a workspace and the global store—the collision this ordering is intended to handle—the desktop sidebar can display both rows because each SessionListItem retains its workspace, but ArchiveSession and SessionPayload transmit only the ID. Searching workspace roots first therefore makes Archive or Restore on the global row operate on the workspace record instead; collisions between workspaces similarly select registry order. Preserve and validate the selected row's workspace/store rather than resolving an ambiguous ID by priority.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant