Skip to content

Workspaces

Workspaces let you make changes to a repository without affecting the shared baseline. Think of them as branches for your data — you can add, revise, and remove things in isolation, then publish your changes as a changeset for review and acceptance.

Without workspaces, every commit immediately modifies the shared repository state. This works for small teams, but larger workflows benefit from:

  • Isolation — experiment freely without affecting other users or subscriptions
  • Review — publish a batch of changes for teammates to review before merging
  • Validation — detect conflicts with baseline changes before they cause problems
  • Rollback — withdraw a changeset to reopen the workspace and iterate

A workspace is a named, user-owned isolation context within a repo. When created, it snapshots the current repo HEAD as its baseline. All commits to the workspace are invisible to the baseline and other workspaces.

Key properties:

PropertyDescription
NameLowercase alphanumeric with hyphens, max 64 chars. committed is reserved for the default workspace.
Statusopen (active), published (locked, changeset under review), abandoned (pending cleanup), permanent (default workspace)
OwnerThe creating user. Only the owner can write to the workspace.
BaselineThe commit the workspace forked from. Used for conflict detection.
TTL30 days by default. Expired workspaces are auto-abandoned.

Workspaces use an overlay pattern:

  • Baseline things (committed to the shared repo) are visible from every workspace.
  • Workspace things (added in a workspace) are only visible within that workspace.
  • Workspace revisions to baseline things shadow the baseline version within the workspace, but the baseline remains unchanged.

This means a workspace “sees” baseline + its own edits, while other workspaces and the baseline see only the shared state.

A changeset is the structured diff from a workspace, submitted for review. It captures all adds, revises, and deactivations as replayable operations. Think of it like a pull request for your data.

Changeset statuses: open (awaiting review), accepting (replay in progress), failed (accept replay stopped with an error and needs investigation), accepted (merged), rejected (sent back), withdrawn (author recalled it).

Terminal window
wh workspace create my-updates -d "Q4 data refresh"

This creates a workspace pinned to the current repo HEAD. All subsequent commits to this workspace are isolated from baseline.

Use the --workspace (or -w) flag on commit and query commands:

Terminal window
# Add a thing in the workspace
wh commit create -w my-updates \
--add acme --shape Company \
--data '{"name":"Acme Corp","revenue":"1.2B"}'
# Query workspace state (sees baseline + workspace overlay)
wh thing head -w my-updates
# View a specific thing in workspace context
wh thing view Company/acme -w my-updates

You can also persist workspace context with wh use so you don’t need to pass -w on every command:

Terminal window
wh use myorg/myrepo -w my-updates
wh thing head # automatically scoped to my-updates

The status command gives a rich overview of workspace state:

Terminal window
wh workspace status my-updates

This shows:

  • Workspace metadata (owner, creation date, expiry countdown)
  • How far behind HEAD the workspace is (commits behind)
  • All changes: added, revised, and deactivated things with draft counts
  • Conflict status and individual conflicts
  • Changeset number (if published)

Before publishing, validate your workspace against the current baseline:

Terminal window
wh workspace validate my-updates

This detects two types of conflicts:

  • Name collision — a thing you added in the workspace now exists in baseline (someone else added it after your workspace was created)
  • HEAD drift — a baseline thing you revised was also modified in baseline after your workspace was created

If your workspace is behind HEAD, rebase to advance the baseline pointer:

Terminal window
wh workspace rebase my-updates

This updates the workspace’s baseline to the current repo HEAD and re-runs conflict detection. If conflicts arise, resolve them with:

  • wh workspace revert my-updates Shape/name — undo workspace changes for a baseline thing, restoring it to baseline state
  • wh workspace discard my-updates Shape/name — remove a thing that was added in the workspace

When your workspace is ready, publish it as a changeset:

Terminal window
wh workspace publish my-updates -m "Q4 data refresh" -r "Annual revenue update"

Add --squash to emit only the effective final state, omitting things that were added then deactivated (if unreferenced):

Terminal window
wh workspace publish my-updates -m "Q4 data refresh" --squash

This:

  1. Validates the workspace (fails if conflicts exist)
  2. Computes the diff (adds, revises, deactivations). With --squash, the diff reflects only the effective final state — things added then deactivated without references are omitted.
  3. Creates a numbered changeset for review
  4. Locks the workspace (no further writes while the changeset is under review or accept replay is running)
Terminal window
# Review operations in detail
wh workspace review my-updates
# Accept (replays operations into baseline)
wh workspace accept my-updates
# Or reject with reason (reopens workspace for iteration)
wh workspace reject my-updates -r "Needs revenue source citations"
# Or withdraw (author only — reopens workspace for iteration)
wh workspace withdraw my-updates

When a changeset is accepted, its operations are replayed through the baseline commit pipeline in chunks of 500, creating real baseline commits. The workspace is then abandoned and garbage-collected.

When a changeset is rejected or withdrawn, the workspace reopens to open status so the author can iterate.

If accept replay fails, the changeset moves to failed and exposes replay progress plus the last error through ChangesetDetail.acceptProgress. The workspace remains published so the failure stays visible for investigation.

For workflows where separate review isn’t needed, merge combines publish and accept in one step:

Terminal window
wh workspace merge my-updates -m "Q4 data refresh"

Workspaces are created with a 30-day TTL. After expiry, stale workspaces are automatically marked as abandoned. Background garbage collection then cleans up all workspace-owned data — things, versions, refs, assertions, embeddings, and commits — in dependency order.

By default, subscriptions ignore workspace commits — only baseline commits trigger actions. This prevents draft activity from firing production automations.

To include workspace commits, set the --workspace-policy flag when creating a subscription:

Terminal window
wh sub create ws-monitor --on Signal --kind webhook \
--filter '{"shape":"Signal"}' --webhook-url https://example.com/hook \
--workspace-policy include

Values: ignore (default) or include.

Workspaces are available through multiple interfaces:

InterfaceCoverage
CLIFull — all wh workspace commands
SDKFull — client.workspace and client.changeset surfaces
MCPFull — 14 dedicated warmhub_workspace_* tools
HTTP APINot yet available — workspace HTTP endpoints are planned

All workspace commands follow the pattern wh workspace <verb>. See the CLI Commands Reference for the full list.

The SDK exposes client.workspace and client.changeset surfaces for programmatic workspace and changeset management.

All workspace and changeset operations are available as 14 dedicated MCP tools (warmhub_workspace_*). Existing query and commit tools accept an optional workspaceName parameter for workspace-scoped operations. See the MCP Tools Reference for details.