Skip to content

Dashboard/Workbench cross-tab optimistic concurrency (revision CAS) #343

Description

@BorisTyshkevich

Context — deferred from #341

#341 made the editable Dashboard and Workbench two editors over one committed StoredWorkspaceV1, with all edits (dashboard commands, saved-query mutations, import/replace) flowing through the single per-tab app.serializeWrite queue. That guarantees same-tab write ordering and consistent same-tab projection/export.

It does not protect against a cross-tab stale overwrite: WorkspaceRepository.commit() is documented last-write-wins with no compare-and-swap (src/workspace/workspace-repository.ts). Two browser tabs (Dashboard in one, Workbench in another) each hold their own serializeWrite chain and their own committedWorkspace baseline. If tab A commits, tab B's next commit — built from B's now-stale baseline — silently clobbers A's change. #341's own "Cross-tab minimum contract" section explicitly allows deferring this as long as reload consistency holds (it does) and same-tab writes are strictly serialized (they are).

Goal

Detect and refuse a stale cross-tab overwrite instead of silently clobbering. Options (pick one during design):

  • Revision CAS in the repository: commit(candidate, expectedRevision?) compares the persisted workspace/dashboard revision and returns a typed conflict result when it moved; callers surface a "workspace changed in another tab — reload" affordance.
  • Storage-event / BroadcastChannel invalidation: a tab that observes another tab's commit refreshes its committedWorkspace baseline (and re-projects) before its next write.

Acceptance

Non-goals

Filed as a scoped follow-up per #341's "Cross-tab minimum contract" section.

Metadata

Metadata

Assignees

No one assigned

    Labels

    inboxFiled mid-task; not yet triaged into the roadmap

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions