Skip to content

Make DashboardAuthoringSession use the shared workspace mutation pipeline before adding callers #349

Description

@BorisTyshkevich

Status

createDashboardAuthoringSession has no production callers on current main; it is referenced only by its implementation and unit tests. This is therefore latent correctness/design debt, not a presently reachable user-facing defect.

Keep the issue open, but it does not block current Dashboard work. It does block wiring this session into Workbench, AI, MCP, or any other production caller.

Problem

DashboardAuthoringSession.commit() currently builds a complete StoredWorkspaceV1 from session-local snapshots and calls WorkspaceRepository.commit() directly.

That bypasses the shared mutation contract introduced by #341/#344:

  1. enter the application workspace write queue;
  2. load the latest committed aggregate at dequeue time;
  3. apply a mutation to that latest aggregate;
  4. commit atomically;
  5. project the committed result.

Once this session gains a live caller, its current implementation can overwrite query, Dashboard, import, rename, or other workspace changes committed by another same-tab producer while the authoring session was open.

Required design

Do not inject a raw repository commit capability into the authoring session.

Inject an application-level mutation seam equivalent to:

mutateWorkspace(
  transform: (latest: StoredWorkspaceV1 | null) =>
    StoredWorkspaceV1 | null | Promise<StoredWorkspaceV1 | null>,
): Promise<WorkspaceCommitResult | null>;

At commit time, the session must rebase its intended Dashboard/query changes onto the dequeue-time latest workspace rather than replacing latest with the session's original workspace snapshot.

The implementation must define explicit conflict semantics for session-local edits when the latest workspace changed incompatibly. It must not silently discard either side.

Scope

Preferred: adapt and retain DashboardAuthoringSession because it remains a useful reusable boundary for future non-DOM callers.

Acceptable alternative: delete the unused module and tests, then recreate it against the shared mutation API when the first production caller is introduced.

This issue is separate from #343. #343 protects cross-tab writes with repository/storage-level optimistic concurrency. This issue ensures this future producer obeys the existing same-tab mutation pipeline.

Acceptance criteria

  • DashboardAuthoringSession no longer receives or calls raw WorkspaceRepository.commit().
  • Its candidate is constructed from the workspace loaded inside the serialized mutation slot.
  • Unrelated query and workspace metadata changes made after session creation survive a session commit.
  • Dashboard revision advances from the latest committed Dashboard revision.
  • A missing or incompatibly changed Dashboard produces an explicit abort/conflict result rather than a stale replacement.
  • Successful commits update the session's clean baseline from the committed result.
  • Failed or aborted commits leave the draft dirty and preserve diagnostics.
  • Unit tests include a mixed-producer regression where another mutation lands after session creation but before session commit.
  • No production caller may be added until these criteria are met.

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    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