Repository navigation
Make DashboardAuthoringSession use the shared workspace mutation pipeline before adding callers #349
Description
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:
- enter the application workspace write queue;
- load the latest committed aggregate at dequeue time;
- apply a mutation to that latest aggregate;
- commit atomically;
- 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.
Resolution
The acceptable deletion alternative was selected for shipping: remove the unused authoring-session module and its dedicated tests before it gains a production caller. Any future non-DOM authoring boundary must be recreated against the shared mutateWorkspace pipeline.
Cleanup acceptance:
- The unused implementation and its session-only API types are deleted.
- The dedicated authoring-session tests are deleted.
- No production caller or stale repository reference remains.
- The surviving pure Dashboard command/model coverage remains at the repository gate.
The behavior criteria below applied to the retained-session design and are superseded by this resolution.
Superseded retention acceptance criteria
-
DashboardAuthoringSessionno longer receives or calls rawWorkspaceRepository.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
- Keep Dashboard and Workbench on one committed workspace state and make exports consistent #341 — shared Dashboard/Workbench workspace state
- fix(#341): one committed workspace for Dashboard + Workbench, consistent exports #344 — serialized dequeue-time workspace mutation pipeline
- Cross-tab workspace consistency: refresh before write and invalidate stale tabs #343 — cross-tab repository-level conflict protection
Activity
BorisTyshkevich commentedon Jul 20, 2026
Plan (small standalone PR, unblocked):
createDashboardAuthoringSessioncurrently takes the rawWorkspaceRepositoryand callsrepository.commit(candidate)with a session-locally built candidate — the exact pre-queue-snapshot pattern PR #344 eliminated from every live producer. Since the module has no callers yet, the fix is an interface change, not a behavior change:repositorycommit dependency with an injectedmutate: App['mutateWorkspace']seam (the session may keep a read-onlyloadCurrentfor its own snapshot needs).latest(re-apply the session's pending command/document delta to it), mirroringrunCommandinsrc/ui/dashboard.ts.mutateWorkspacehelpers added totests/helpers/fake-app.tsin fix(#341): one committed workspace for Dashboard + Workbench, consistent exports #344, including one mixed-producer regression.Alternative if we'd rather not maintain speculative code: delete the module and recreate it against
mutateWorkspacewhen the first AI/MCP caller lands. Either resolution prevents the footgun; wiring it to the seam preserves the design investment.[-]dashboard-authoring-session commits outside the serialized workspace write queue[/-][+]Make DashboardAuthoringSession use the shared workspace mutation pipeline before adding callers[/+]refactor(#349): remove unused dashboard authoring session (#382)