Skip to content

Make workspace changes take effect on restart #126

Description

@ultmaster

Summary

Treat the workspace path as startup configuration instead of supporting live workspace/storage switching. Selecting a different workspace should persist the desired path and require a restart; the next server process should mount that workspace once during startup.

Current behavior

In free mode, the renderer persists the selected path (Electron uses <userData>/workspace.json; browser mode uses localStorage). On launch, the server starts without HUABU_WORKSPACE, and the renderer calls PUT /api/workspace to activate the remembered path.

Changing the path while the server is running therefore requires a full online transition:

  • prepare and migrate the target workspace;
  • stage its structured and blob storage connections;
  • atomically publish the new workspace path and storage mount;
  • protect in-flight operations with workspace leases;
  • detach and close the previous mount;
  • invalidate workspace-scoped caches and handles.

This lifecycle is necessary if live switching is a product requirement, but it adds substantial complexity before connection-holding backends such as SQLite, Postgres, or Azure Blob Storage are implemented.

Proposal

Make workspace changes restart-bound:

  1. When the user selects a workspace, validate the absolute path and persist it as the desired workspace.
  2. Tell the user that a restart is required, or restart the desktop application/server automatically.
  3. Before forking the server, Electron reads <userData>/workspace.json and injects the selected path as HUABU_WORKSPACE.
  4. The server prepares the workspace and mounts storage once during startup.
  5. While running, the active workspace is immutable. Requests attempting to change it should be rejected or return a restartRequired result without mutating process state.

For standalone/server deployments, HUABU_WORKSPACE remains the source of truth. Browser localStorage cannot configure a server before it starts, so browser-only deployments should not imply that a renderer-owned path can safely change server storage.

The host-specific persisted path should remain owned by the Electron main process because it already owns both workspace.json and the server child-process environment.

Expected simplification

If live switching is removed, the storage lifecycle can be reduced to:

process startup -> prepare workspace -> initialize/mount storage -> serve -> close storage on shutdown

This should allow us to remove or substantially simplify:

  • StagedStorage, stageStorage(), and commit/abort publication;
  • detachStorage() and stale-mount recovery;
  • atomic workspace-path/storage-mount swapping;
  • workspace operation leases whose only purpose is preventing an online switch;
  • cache invalidation paths that exist only to move a running process from workspace A to workspace B.

closeStorage() should remain for graceful shutdown. A storage mount may still retain its workspacePath as explicit ownership/diagnostic metadata.

UX considerations

  • Clearly show that changing the workspace requires a restart.
  • Preserve the current recent-workspaces list.
  • Validate the selected directory before saving it.
  • Define recovery behavior when the saved workspace cannot be prepared or mounted at the next launch (for example, start unconfigured and show the workspace picker with the startup error).
  • Avoid presenting a successful workspace switch until the restarted server has mounted the selected workspace.

Acceptance criteria

  • Electron passes the persisted workspace path to its server child at startup.
  • The active workspace cannot change during a server process lifetime.
  • Selecting a different workspace persists the choice and results in a restart-required flow.
  • Startup failures provide a recoverable path instead of leaving the desktop application unusable.
  • Standalone deployments continue to support HUABU_WORKSPACE.
  • Online remount-only lifecycle code and tests are removed or simplified accordingly.

Pending work, in ship order

  1. Merge PR feat(workspace): make workspace changes take effect on restart #129 to establish the restart-bound, one-Workspace-per-process baseline and remove online remount machinery.
  2. Rebase PR feat(storage): multi-backend storage phase 4.6 — one Space handle, backend-neutral application, and Workspace mount #125 onto the updated main; remove its overlapping workspace commits and staged Workspace-mount implementation, then resolve the remaining conflicts.
  3. Run the full repository verification and merge the trimmed Phase 4.6 portability work: portable reads, the composed Space handle, scoped blob/extensions, capability guards, application migration, and backend-boundary tests.
  4. Write and approve a separate first-class multi-workspace specification covering Workspace identity, catalogue operations, backend selection, connection lifetime, legacy Disk adoption, SQL default-Workspace behavior, and API/UX semantics.
  5. Implement the storage foundation from that specification: Workspace-owned handles, (workspaceId, spaceId) indexes and constraints, the Disk adapter, SQL Workspace records, and compatibility migration/defaulting.
  6. Implement Workspace management and no-restart selection in the server API, desktop host, and web UI.
  7. Add end-to-end coverage for multiple Disk Workspaces and SQL default/create/select flows, including restart, failure recovery, and legacy adoption.

— posted by Codex (via the issue-tracker skill)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions