Skip to content

Workspace Architecture

ThinkWork workspaces are split into two kinds of durable state:

  • Files hold working and narrative content: context, memory notes, docs, decisions, artifacts, handoffs, skills, and instructions the agent reads while working.
  • The database holds structured workflow state: task status, Goal lifecycle, review policy, access grants, thread bindings, and other values that need transactions.

That split is the point of the architecture. A fact has one authoritative home. Files are portable, readable, diffable, and natural for an agent running in a filesystem. The database is transactional, constrained, and safe for many users, automations, and agent workers updating structured state at the same time.

flowchart TB
subgraph Factory["Factory source folders"]
Agent["Agent source\nidentity, instructions, skills"]
Space["Space source\nproject docs, workflow templates, knowledge"]
User["User source\npersonalization and memory notes"]
end
subgraph DB["Database"]
Goals["Goals and linked tasks"]
Access["Access grants and thread binding"]
Policy["Review policy, owner, mode"]
end
Factory --> Compose["Compose by reference"]
DB --> Status["Render read-only status files"]
Compose --> Runtime["Per-thread runtime workspace\n/workspace"]
Status --> Runtime
Runtime --> Turn["Pi turn\nAgentCore, desktop, or mobile"]
Turn --> Reconcile["Reconcile file changes through the API"]
Reconcile --> Factory
Turn --> Tools["Structured tools and resolvers"]
Tools --> DB

The source workspace is the editable side of the workspace. Settings -> Workspace shows it as three top-level folders:

Workspace
├── Agent
├── Spaces
└── User

Agent is the tenant-wide baseline. Spaces contains one folder per Space. User contains the current user’s personalization and memory notes.

The runtime workspace is what the agent sees for one Thread turn. It is rendered per Thread under a stable thread folder and hydrated into /workspace for Pi on AgentCore, desktop, and mobile. Runtime rendering is by reference: it writes a hydrate manifest that points back to the source files instead of copying every Agent, Space, and User file into a permanent per-user tuple.

The runtime does not show the same top-level source folders. It uses the Agent source as the root, merges User context into the root, and mounts only the active Space as singular Space/:

/workspace
├── AGENTS.md
├── CONTEXT.md
├── USER.md
├── memory/
├── skills/
├── workspaces/
└── Space/
├── CONTEXT.md
├── artifacts/
├── docs/
├── goals/
└── plans/

The canonical source folders are tenant-scoped in S3:

tenants/{tenant}/
├── agents/{agent-folder}/
│ ├── AGENTS.md
│ ├── CONTEXT.md
│ ├── skills/
│ └── memory/
├── spaces/{space-folder}/
│ ├── CONTEXT.md
│ ├── artifacts/
│ ├── docs/
│ ├── goals/
│ └── plans/
├── users/{user-folder}/
│ ├── USER.md
│ └── memory/
└── threads/{thread-folder}/
├── .hydrate_manifest.json
├── .rendered_at
├── GOAL.md
├── PROGRESS.md
├── DECISIONS.md
├── ARTIFACTS.md
└── HANDOFFS.md

Folder names are human-readable and filesystem-safe. The stable identity remains the database UUID; the folder name is the readable path.

GOAL.md and PROGRESS.md are status files, but they are not the authority for status. They are read-only projections rendered from database rows so the agent can understand the work in normal workspace form.

When an agent completes a task, it uses the task-status tool. That tool writes the database transaction, then the status files can be re-rendered from the new structured state. Editing PROGRESS.md text does not change the task row.

Every Pi runtime follows the same turn shape:

  1. Compose. Resolve the Agent, Space, User, Thread, and database status sources.
  2. Hydrate. Download the manifest-backed files into /workspace.
  3. Run. The agent reads and writes files, calls tools, and produces the reply.
  4. Reconcile. File-side changes go through the finalize path. The API checks provenance, lanes, access, secret scanning, and object freshness before writing allowed source files back to S3.

Structured state changes do not go through reconcile. They go through tools and resolvers that write the database.

Workspace sync is incremental. Desktop, mobile, and AgentCore check source and manifest freshness, then hydrate the files needed for the turn. They should not download the entire tenant bucket before every turn.

Structured task and Goal progress still depends on platform tools and resolvers. If a user says “DocuSign is complete”, the agent should route that intent through task-status tooling; editing PROGRESS.md text is not an authoritative status change.