Skip to content

fix(workspace): restore last selection after restart - #7067

Merged
lefarcen merged 12 commits into
mainfrom
fix/restore-last-workspace
Aug 18, 2026
Merged

fix(workspace): restore last selection after restart#7067
lefarcen merged 12 commits into
mainfrom
fix/restore-last-workspace

Conversation

@lefarcen

Copy link
Copy Markdown
Contributor

Why

QA found that quitting and reopening the client did not return users to the workspace they had last selected. The web client kept its selection only in tab-scoped sessionStorage, while the daemon's selection store was no longer updated, so a cold client fell back to Personal/default instead of the user's last workspace.

The same investigation found that workspace resolution still depended on Vela's account-global /api/v1/workspaces/current endpoint. That state cannot represent multiple tabs or clients using different workspaces, so this PR removes that dependency and keeps request authority explicitly workspace-scoped.

What users will see

After selecting a workspace, quitting Open Design, and reopening it, the client returns to that workspace when the membership is still active. If the saved workspace was removed or deleted, startup safely falls back to an available workspace.

Already-open tabs remain independently scoped: the saved workspace is only a cold-start preference and never authorizes data-plane requests.

Surface area

  • UI — new page / dialog / panel / menu item / setting / empty state in apps/web or apps/desktop (including Electron menu bar)
  • Keyboard shortcut — new or changed
  • CLI / env var — new od subcommand or flag, new tools-dev / tools-pack flag, or new OD_* env var
  • API / contract — new /api/* endpoint, new SSE event, or changed shape in packages/contracts
  • Extension point — new entry under skills/, design-systems/, design-templates/, or craft/, or change to the skills protocol
  • i18n keys — added new translation keys (see TRANSLATIONS.md for the locale workflow)
  • New top-level dependency — adding any new entry to the root package.json (dependencies or devDependencies); workspace-package package.json files are out of scope. Include a paragraph on what we get vs. what bytes we ship (see CONTRIBUTING.md → Code style)
  • Default behavior change — changes what existing users experience without opting in (default model, default setting, file/SQLite schema, auto-network on startup, auto-install)
  • None — internal refactor, docs, tests, or translation update only

Screenshots

Not applicable: this changes restart selection behavior without adding or visually changing a UI entry point.

Bug fix verification

  • Test path that reproduces the bug: apps/web/tests/useWorkspaceContext.cache.test.tsx (restores the daemon-saved workspace when a new client session has no tab selection)
  • Did the test go red on main and green on this branch? Yes. On main, the cold client context remained null/fell through instead of selecting the saved Team workspace; on this branch all four tests pass.
  • Cross-process restart coverage: e2e/tests/collab/workspace-switch-and-billing.test.ts persists a Team selection, restarts the daemon over the same data root, and verifies both restoration and stale-membership cleanup.

Validation

  • corepack pnpm install --frozen-lockfile
  • corepack pnpm guard
  • corepack pnpm typecheck
  • corepack pnpm --filter @open-design/daemon exec vitest run -c vitest.config.ts tests/vela-workspace-context.test.ts tests/collab/active-workspace-selection.test.ts tests/collab/workspace-multi-client-scope.test.ts tests/collab/workspace-scope.test.ts tests/collab-presence-routes.test.ts tests/collab/workspace-switch-warms-caches.test.ts tests/workspace-context-authority-server-wiring.test.ts — 111 passed
  • corepack pnpm --filter @open-design/web exec vitest run -c vitest.config.ts tests/useWorkspaceContext.cache.test.tsx — 4 passed
  • corepack pnpm --filter @open-design/e2e exec vitest run -c vitest.config.ts tests/amr/turn.test.ts tests/collab/headerless-mutation.test.ts tests/collab/new-account-default-workspace.test.ts tests/collab/reconcile-unbound-authority.test.ts tests/collab/team-project-catalog.test.ts tests/collab/workspace-invite-flow.test.ts tests/collab/workspace-skill-resource-isolation.test.ts tests/collab/workspace-switch-and-billing.test.ts — 20 passed
  • Repository scan for /api/v1/workspaces/current, workspaces/current, and WORKSPACE_CURRENT_PATH — 0 matches

@lefarcen lefarcen added the needs-validation Runtime change detected; needs human or /explore agent validation. label Aug 18, 2026
@lefarcen

Copy link
Copy Markdown
Contributor Author

🧪 This PR has changes that need a manual QA pass before merge — please hold off self-merging for now; we'll loop QA in once it's merge-ready (and design/product have signed off, where applicable).

@lefarcen
lefarcen requested a review from mrcfps August 18, 2026 11:34
@lefarcen lefarcen added size/XL PR changes 700-1500 lines risk/high High risk: apps/desktop, daemon, auth, migration, workflows, package deps type/bugfix Bug fix labels Aug 18, 2026
@github-actions

github-actions Bot commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

Visual regression review

Head: 04c4bbb · Base: 42faa84

0 changed · 49 unchanged · 0 new without baseline · 0 failed

Unchanged cases
Case Main PR Diff
visual-avatar-local-agent-list
0 px (0.00%)
main pr diff
visual-avatar-local-agent-list-panel
0 px (0.00%)
main pr diff
visual-avatar-menu
0 px (0.00%)
main pr diff
visual-avatar-menu-panel
0 px (0.00%)
main pr diff
visual-avatar-open-design-model-picker
0 px (0.00%)
main pr diff
visual-critical-settings
0 px (0.00%)
main pr diff
visual-critical-workspace
0 px (0.00%)
main pr diff
visual-critical-workspace-preview
0 px (0.00%)
main pr diff
visual-design-system-detail
0 px (0.00%)
main pr diff
visual-design-systems
0 px (0.00%)
main pr diff
visual-home
0 px (0.00%)
main pr diff
visual-home-catalog
0 px (0.00%)
main pr diff
visual-home-context-picker
0 px (0.00%)
main pr diff
visual-home-context-picker-popover
0 px (0.00%)
main pr diff
visual-home-plugin-filter
0 px (0.00%)
main pr diff
visual-home-plugin-use-staged
0 px (0.00%)
main pr diff
visual-home-plugin-use-with-query
0 px (0.00%)
main pr diff
visual-home-staged-attachment
0 px (0.00%)
main pr diff
visual-integrations
0 px (0.00%)
main pr diff
visual-integrations-mcp
0 px (0.00%)
main pr diff

Visual diff is advisory only and does not block merging.

@lefarcen
lefarcen force-pushed the fix/restore-last-workspace branch from e983f6d to 9ad9236 Compare August 18, 2026 12:09
@lefarcen
lefarcen force-pushed the fix/restore-last-workspace branch from 4a7c40b to a912103 Compare August 18, 2026 12:16
@lefarcen
lefarcen requested review from Siri-Ray and removed request for mrcfps August 18, 2026 12:43

@Siri-Ray Siri-Ray left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@lefarcen Thanks for the careful workspace-restoration work. I verified the persisted restart-default flow, exact request authority, stale-membership recovery, and the focused daemon/web/e2e suites. The restoration path looks solid; I’m leaving one non-blocking follow-up on the directory-only seat sentinel, where the entry gate and invite dialog currently disagree.

🔁 Powered by Looper · runner=reviewer · agent=codex · An autonomous AI dev team for your GitHub repos.

Comment thread apps/web/src/components/EntryNavRail.tsx Outdated
@lefarcen
lefarcen requested a review from Siri-Ray August 18, 2026 13:04

@Siri-Ray Siri-Ray left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@lefarcen Thanks for the careful workspace-restoration work and the quick seat-capacity follow-up. I verified the persisted restart default, stale-membership recovery, exact request authority, multi-client isolation, and the focused daemon/web/E2E paths; the repository gates and live CI matrix are green. The main flow looks solid. I’m leaving one non-blocking error-handling follow-up where a rejected persistence write can still change the daemon’s in-memory restart default.

🔁 Powered by Looper · runner=reviewer · agent=codex · An autonomous AI dev team for your GitHub repos.

Comment thread apps/daemon/src/routes/collab-context.ts
@lefarcen
lefarcen requested a review from Siri-Ray August 18, 2026 14:23
@lefarcen lefarcen added the backport release/v0.20.0 Backport this fix to release/v0.20.0 label Aug 18, 2026

@Siri-Ray Siri-Ray left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@lefarcen Thanks for the careful workspace-restoration work and the follow-ups that made persistence failures state-neutral. I verified the restart-default flow, exact request authority, stale-membership recovery, multi-client isolation, and the focused daemon/web/E2E paths; the repository gates and live CI matrix are green. The main flow looks solid. I’m leaving one non-blocking observability follow-up for the directory-only seat-capacity sentinel.

🔁 Powered by Looper · runner=reviewer · agent=codex · An autonomous AI dev team for your GitHub repos.

Comment thread apps/web/src/components/EntryNavRail.tsx Outdated
@lefarcen
lefarcen requested a review from Siri-Ray August 18, 2026 14:41
@lefarcen
lefarcen requested review from Siri-Ray and removed request for Siri-Ray August 18, 2026 14:48

@Siri-Ray Siri-Ray left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@lefarcen Thanks for the careful workspace-restoration work and the quick follow-ups on persistence and seat-capacity handling. I verified the restart-default flow, directory-only authority, stale-membership recovery, multi-client request isolation, and the focused daemon/web/E2E coverage; local validation and the live CI matrix are green. I found one non-blocking concurrency issue in stale-selection cleanup that can erase a newer restart default from another tab.

🔁 Powered by Looper · runner=reviewer · agent=codex · An autonomous AI dev team for your GitHub repos.

Comment thread apps/daemon/src/routes/collab-context.ts Outdated
@lefarcen
lefarcen requested a review from Siri-Ray August 18, 2026 15:07

@Siri-Ray Siri-Ray left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@lefarcen Thanks for the careful workspace-restoration work and the follow-up that made stale cleanup compare-and-clear. I reviewed every changed range and rechecked the persisted restart default, directory-only authority, stale-membership recovery, multi-client isolation, and focused daemon/web/E2E coverage. The local repository gates and live CI matrix are green. I found one remaining non-blocking ordering window where stale recovery can persist its fallback after a newer user selection.

🔁 Powered by Looper · runner=reviewer · agent=codex · An autonomous AI dev team for your GitHub repos.

Comment thread apps/daemon/src/collab/vela-workspace-context.ts Outdated
@lefarcen
lefarcen requested a review from Siri-Ray August 18, 2026 15:49

@Siri-Ray Siri-Ray left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@lefarcen Thanks for the careful workspace-restoration work and the follow-ups that hardened persistence and stale recovery. I reviewed every changed range and verified the saved cold-start default, directory-only request authority, stale-membership fallback, multi-tab isolation, unknown seat handling, and the atomic conditional replacement path. The focused daemon, web, E2E, and browser checks pass locally, root guard and typecheck pass, and the live CI matrix is green. Nicely done—this is a thoughtful fix. 🙌

🔁 Powered by Looper · runner=reviewer · agent=codex · An autonomous AI dev team for your GitHub repos.

@lefarcen
lefarcen requested a review from AmyShang-alt August 18, 2026 16:11
@lefarcen lefarcen removed the needs-validation Runtime change detected; needs human or /explore agent validation. label Aug 18, 2026
@lefarcen
lefarcen added this pull request to the merge queue Aug 18, 2026
Merged via the queue into main with commit 879236e Aug 18, 2026
28 checks passed
@open-design-release-bot

Copy link
Copy Markdown
Contributor

Successfully created backport PR for release/v0.20.0:

open-design-release-bot Bot added a commit that referenced this pull request Aug 18, 2026
* fix(workspace): restore the last selection on restart

* test(workspace): cover persisted restart default

* fix(workspace): reuse directory authority for context reads

* test(workspace): align unknown seat invite behavior

* test(workspace): cover unknown seat invite fallback

* fix(workspace): preserve unknown invite capacity

* fix(workspace): commit selection after persistence

* fix(workspace): preserve unknown seat analytics

* fix(workspace): guard stale selection cleanup

* fix(workspace): make stale recovery atomic

(cherry picked from commit 879236e)

Co-authored-by: lefarcen <935902669@qq.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backport release/v0.20.0 Backport this fix to release/v0.20.0 risk/high High risk: apps/desktop, daemon, auth, migration, workflows, package deps size/XL PR changes 700-1500 lines type/bugfix Bug fix

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants