Skip to content

Workspace

What Workspace is

Workspace is the project boundary inside clumsies. It is where shared organizational behavior meets project-specific knowledge and local runtime state.

That sentence hides three different responsibilities, so it is worth unpacking them.

A workspace selects Library-backed behavior. It owns project context. It also acts as the server-side anchor for the manifest and cache that local runtime reads from.

This is why workspace is more than a folder binding and more than a repo name.

What a workspace contains

A workspace combines several distinct object types that should not be collapsed into one bucket.

PartOwnershipWhat it is
selected rules and workflowsreference to Libraryshared behavioral assets chosen for this project
selected bundlesreference to Librarynamed group selections that expand into behavior content
context filesworkspace-ownedproject knowledge such as specs, ADRs, research, design notes
manifestHub-generatedcurrent indexed snapshot of workspace runtime state
local draftslocal in-progress workedits not yet merged into Library or workspace mainline

The first three rows are the most important. They explain why workspace exists as its own object rather than being implied by a local checkout path.

Workspace is not the same thing as a repo

The specs are explicit about this: a workspace can bind to more than one local path and does not need to be reduced to a single repository checkout.

The server-side workspace ID is the real identity. Local paths are bindings recorded by the client. That distinction matters because the product is trying to model a project boundary, not just a folder on one machine.

Binding: how local paths attach to a workspace

The current client records workspace bindings in:

text
~/.clumsies/config.toml

That file stores at least:

FieldMeaning
server.urlHub base URL
[[workspaces]].namelocal label
[[workspaces]].ws_idauthoritative workspace ID
[[workspaces]].pathslocal filesystem paths bound to this workspace

This means a local path lookup is a resolution step, not identity creation. The client does not infer a workspace from a folder name. It resolves the folder through the binding config and then works against the authoritative ws_id.

A simplified example looks like this:

toml
[server]
url = "http://127.0.0.1:8400"

[[workspaces]]
name = "clumsies"
ws_id = "ws-4a5c282474c9b5d9385dec0502267738"
paths = [
  "/Users/lilhammer/workspace/clumsies",
  "/Users/lilhammer/workspace/clumsies-docs"
]

That example makes two design points concrete.

First, both local paths bind to the same workspace ID. Second, the path list is only local resolution state. The server-side workspace still remains the real project identity.

Manifest: the current workspace snapshot

The manifest is the bridge between Hub authority and local runtime. In the current implementation it is written to:

text
~/.clumsies/workspaces/{ws_id}/manifest.json

The current top-level schema is:

FieldMeaning
ws_idworkspace identity
nameworkspace name
revisioncurrent workspace snapshot revision
rulesstable-ID keyed map of selected Library behavior
contextstable-ID keyed map of workspace context

The current entry schema inside rules and context includes:

FieldMeaning
pathruntime-relative path for the item
hashcontent hash used during sync
descriptionoptional schema-carried description

A simplified example looks like this:

json
{
  "ws_id": "ws-1",
  "name": "demo",
  "revision": 7,
  "rules": {
    "p-1": {
      "path": "rule/coding/00_COMPATIBILITY.md",
      "hash": "sha256:def",
      "description": ""
    }
  },
  "context": {
    "ctx-1": {
      "path": "spec/ARCHITECTURE.md",
      "hash": "sha256:abc",
      "description": ""
    }
  }
}

There are two design choices here that deserve explicit explanation.

First, the manifest is not just a list of names. It is the indexed state of the workspace.

Second, rules and context are keyed by stable IDs rather than paths. That keeps identity stable across rename. The system can understand that an item moved without pretending it was deleted and recreated.

For example, if a rule keeps the same rule_id but moves from rule/coding/STYLE.md to rule/style/STYLE.md, the manifest only needs to update the path field for that one entry. The client does not need to treat it as a delete plus a brand-new unrelated rule.

Why manifest matters

The manifest does three jobs at once.

It tells the client what the workspace currently contains. It gives sync a stable object to compare against. It gives runtime surfaces one shared snapshot instead of forcing each client to invent its own discovery path.

That is why manifest belongs in the workspace model, not only in a sync page.

Cache: the materialized side of workspace runtime

Each workspace also has a dedicated local runtime directory:

text
~/.clumsies/workspaces/{ws_id}/

The synced content lives under:

text
~/.clumsies/workspaces/{ws_id}/cache/

The current implementation materializes at least:

Path under cacheMeaning
rule/synced rules and workflows selected by the workspace
context/synced workspace context files
META_PROMPT.mdcached meta prompt used by agent bootstrap

This is where the workspace model touches runtime directly.

The local workspace directory has two layers:

PathRole
~/.clumsies/workspaces/{ws_id}/manifest.jsonworkspace snapshot and sync index
~/.clumsies/workspaces/{ws_id}/cache/materialized files used by local runtime

That split explains practical behavior. Sync can skip unchanged content because the manifest tells it what should exist and which hash each item should have. MCP can serve from local state because the cache already contains the materialized files.

Context belongs to the workspace side

Context is where project-specific facts live. In the current design, that includes things like:

  • architecture documents
  • specs
  • ADRs
  • research notes
  • design material
  • journals

The important point is not the file type. The important point is ownership and role. Context is workspace knowledge.

That means context should not be explained as a special kind of Library content. It may be rendered into cache in a similar way, but it has a different collaboration destination and a different authority model.

Library selections stay Library selections

Rules, workflows, and bundles remain Library-backed even after a workspace selects them. The workspace does not become their new authority. It becomes the project boundary that selects which shared behavioral assets should be active for this project.

That distinction is what keeps the object model clean:

  • Library owns shared behavior
  • workspace owns project knowledge
  • manifest brings both into one runtime snapshot

Drafts and review flow

Workspace also matters because real editing happens around it.

A local draft is not the same thing as synced cache. Cache is pulled state. Draft is in-progress work.

The collaboration split stays important here:

  • rule-oriented edits move back toward Library proposal and review flow
  • context-oriented edits move toward workspace-owned mainline

This is one of the reasons the workspace model exists at all. Without it, rule lifecycle and project-knowledge lifecycle would collapse into one ambiguous bucket.

Workspace membership and authorization

The workspace boundary is also where membership starts to matter. A workspace is not only a content container. It is an authorization boundary for who can bind, inspect, edit, and review project-specific material.

That is why the server-side workspace object has to stay authoritative. If local folders were treated as identity, permission checks would become guesswork.

Why Workspace matters in the docs

If docs talk only about Library, the system looks too centralized. If docs talk only about local cache, the system looks too accidental. Workspace is the object that explains how shared behavior, project-specific knowledge, sync, and runtime all meet in one place.