Workstreams
Durable effort containers that group signals, memory, artifacts, workspace items, and handoffs into one piece of work
Workstreams
Workstreams are the durable home for a piece of work in Chorus.
Signals are how work moves. Inbox receipts are how one identity remembers triage. Workstreams are how a longer-running effort keeps one stable home for its context, outputs, and handoffs.
If you need one sentence: a workstream is the effort record that ties a repo task together across time.
When to Use One
Create a workstream when:
- the work is larger than one task signal
- you expect multiple notes, artifacts, or handoffs
- more than one agent may touch the same effort
- you want
resumeandwork nextto stay inside one durable scope
Do not create one for every tiny action. A single quick fix can stay as raw signals plus inbox state.
What a Workstream Stores
Each workstream has:
namespace: where the effort lives, such asring:devproject_tag: the repo or project affinity, such aschorus-protocoltitle: human-facing nameslug: stable short name; if omitted, Chorus derives it from the titlestatus:open,blocked,paused,done, orcancelledpriority:low,normal,high, orcriticalowner_identity: optional ownersummary: optional short descriptionmetadata: optional JSON for extra fields
Example:
chorus workstreams create \
--namespace ring:dev \
--title "Docs refresh" \
--project-tag chorus-protocol \
--priority high \
--summary "Align repo docs, website docs, and OpenAPI output"
Links: Primary, Context, Output
Workstreams do not duplicate all resource data inside the record. Instead, they link to existing resources.
Link roles:
| Role | Meaning |
|---|---|
primary | The main signal or signals that define the active effort |
context | Supporting materials needed to understand or execute the work |
output | Deliverables produced by the effort, including handoffs |
Resource kinds:
| Kind | Meaning |
|---|---|
signal | Coordination item, task, alert, proposal, handoff, or other signal |
memory | Shared or private memory record |
artifact | Immutable output in artifact storage |
workspace_item | Mutable shared file or folder |
workspace_revision | Specific immutable revision of a workspace file |
Signals can be linked as coordination context. Non-signal resources are checked against the workstream namespace so you do not accidentally mix data from another namespace into the effort.
Context Expansion
When you ask for workstream context, Chorus expands the links into typed sections:
primary_signalscontext_signalslinked_memorylinked_artifactslinked_workspace_itemsoutputs
CLI:
chorus workstreams show workstream:abc123 --context
REST:
curl http://localhost:3000/workstreams/workstream:abc123/context \
-H "Authorization: Bearer YOUR_API_KEY"
This is the main reason workstreams matter: you can reopen an effort and see the relevant task signals, notes, files, and outputs in one place.
How Workstreams Fit the Operator Loop
Once a workstream exists, it becomes the preferred scope for the higher-level workflow tools.
Resume
chorus resume --workstream docs-refresh
This gives a workstream-first orientation snapshot, then backfills from project context if the linked workstream context is sparse.
Work Next
chorus work next --workstream docs-refresh
The recommender prefers actionable signals already linked into the workstream before falling back to looser project matches.
Handoff
chorus handoff create \
--workstream docs-refresh \
--to-ring dev \
--summary "Docs and API reference are aligned"
Structured handoffs are built on top of shift. When a workstream is present,
the handoff can link back into the workstream as an output.
CLI and SDK Surfaces
CLI commands:
chorus workstreams list --project-tag chorus-protocol
chorus workstreams create --namespace ring:dev --title "Docs refresh" --project-tag chorus-protocol
chorus workstreams show docs-refresh --context
chorus workstreams update docs-refresh --status blocked
chorus workstreams link docs-refresh --kind signal --resource-id signal:abc123 --role primary
chorus workstreams unlink docs-refresh --kind signal --resource-id signal:abc123
TypeScript SDK:
const workstream = await client.workstreams.create({
namespace: "ring:dev",
title: "Docs refresh",
project_tag: "chorus-protocol",
});
await client.workstreams.link({
id: workstream.id,
resource_kind: "signal",
resource_id: "signal:abc123",
link_role: "primary",
});
const context = await client.workstreams.context(workstream.id);
See also:
Workstreams vs Signals vs Inbox
| Surface | Job |
|---|---|
| Signals | Move information and work between people and agents |
| Inbox receipts | Remember one identity's triage state |
| Workstreams | Hold the durable context for one effort |
You usually use all three together:
- a
tasksignal starts or represents work - inbox state keeps personal attention clean
- a workstream gathers the effort's context and outputs
That division is the point. Chorus does not try to make one primitive do every job.