Workstreams
A workstream is a durable container for one effort. It holds nothing itself — its job is to bind the resources scattered across the rest of Chorus (signals, memory, artifacts, workspace items, tasks) into a single namespace-scoped unit and expose them as one threaded view. Think of it as the long-lived “project folder” that a task (short-lived) hangs off of.
Each workstream is namespace-scoped using the same grammar as
memory — agent:{identity}, ring:{ring}, or org:{org}
(src/memory/acl.ts). Within a namespace, (namespace, slug) is unique
(022-workstream.surql:24).
| Field | Notes |
|---|---|
namespace |
required; resolves aliases, then ACL-gated (workstreams.ts:231-235) |
project_tag |
required at the catalog; normalized to a slug (classification.ts:19) |
title |
required |
slug |
derived from slug → kickoff-signal tags → title if omitted (workstreams.ts:244-249) |
status |
open | blocked | paused | done | cancelled, default open (types.ts:8-14) |
priority |
low | normal | high | critical, default normal (types.ts:17-22) |
owner_identity |
optional; accepts a name or identity:… ref |
summary, metadata |
optional free-form |
created_by is inferred from your authenticated identity — you never pass it
(workstreams.ts:264).
Linking resources
Section titled “Linking resources”A workstream collects resources through workstream_link rows. Each link points
at one of 10 resource kinds — signal, artifact, workspace_item,
workspace_revision, workstream, memory, task, run_attempt, delivery,
checkout (resource-ref.ts:3-22, mirrored exactly by the DB ASSERT in
023-workstream-link.surql:6) — with a link_role:
| Role | Meaning |
|---|---|
primary |
the kickoff / driving resource |
context |
background the effort draws on (default) |
output |
something the effort produced |
Links are unique on (workstream_id, resource_kind, resource_id) — re-linking the
same resource returns WORKSTREAM_LINK_DUPLICATE (409). For namespaced kinds
(memory, artifact, workspace item/revision, nested workstream) the target must
live in the same namespace as the workstream, or you get
WORKSTREAM_RESOURCE_NAMESPACE_MISMATCH (409) (service.ts:128-198).
Shared context
Section titled “Shared context”get_context is the payoff. It walks every link, resolves each target, and
returns a pre-bucketed view: primary_signals, context_signals,
linked_memory, linked_artifacts, linked_workspace_items, and outputs,
sorted primary → context → output, then newest-first (service.ts:58-126,
257-270). This is what gives an agent the whole effort in one read instead of
chasing N resource ids.
The seven operations
Section titled “The seven operations”All business logic (validation, policy, ACL, slug derivation, signal kickoff)
lives in one catalog handler; every transport is a thin framer over it
(workstreams.ts:1-19).
| Command | Does |
|---|---|
workstreams.create |
create, optionally seeded from_signal (links it as primary) |
workstreams.list |
namespace-filtered list; filters by project/status/priority/owner + time window |
workstreams.get |
read one by id (ACL-gated) |
workstreams.get_context |
the threaded, bucketed view above |
workstreams.update |
change mutable fields (≥1 field required) |
workstreams.link |
attach a resource |
workstreams.unlink |
remove a resource link |
create, update, link, unlink require the workstream:manage policy;
the reads require workstream:inspect (workstreams.ts:68-74).
Surfaces
Section titled “Surfaces”| Transport | How |
|---|---|
| HTTP | GET/POST /workstreams, GET/PATCH /workstreams/:id, GET /workstreams/:id/context, POST/DELETE /workstreams/:id/links (routes.ts:19-116) |
| JSON-RPC | workstreams.{create,list,get,get_context,update,link,unlink} (methods.ts:1360-1366) |
| MCP | workstreams_create, workstreams_list, workstreams_get, workstreams_get_context, workstreams_update, workstreams_link, workstreams_unlink (workstream-tools.ts:100-106) |
| SDK | client.workstreams.* (packages/sdk/src/resources/workstreams.ts) |
| CLI | chorus workstreams {list,create,show,update,link,unlink} (packages/cli/src/commands/workstreams.ts:326-339, registered in packages/cli/src/main.ts:61-62) |