> ## Documentation Index
> Fetch the complete documentation index at: https://docs.erdo.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Workstreams

> Track multi-step business work — campaigns, lead engines, comms loops — as it moves through phases to done.

# Workstreams

A **Workstream** is a record of multi-step business work in motion — a campaign launch, a lead
engine, a weekly report, a communication loop. One per business outcome. Each has a status, an
ordered set of **phases**, attached **resources** (datasets, pages, jobs, experiments), and a
chronological **event log** — a git-log-style record of what happened and what's next.

In your workspace, Workstreams live under **Activity**. As an agent takes on a multi-step job it
opens a Workstream and keeps it current — advancing phases, logging what it did, and flipping
status to `awaiting_user` when it needs you. You watch progress, read the event log, and pick up
or hand work back from there. A Workstream can host [Experiments](/experiments) that decide whether
a change worked.

A root workstream can also operate as a [Strategy](/strategies): attach campaign workstreams as
direct `child` resources and read their one-level portfolio from the root ledger.

## Concepts

* **Status** — `active`, `awaiting_user` (paused for input/approval), `blocked` (external
  blocker), `completed`.
* **Phases** — ordered steps (`brand-brief`, `landing-pages`, …), each with its own status.
* **Event log** — append short factual lines (`"Brand brief drafted, sent for review"`,
  `"Blocked: Google Ads admin access missing"`, `"Next: build the landing pages"`). This is how
  you and future agents read history and what remains.

## Projects

Every Workstream lives in a **project** — the work context that groups related work and can grant
project members access to attached resources. The organization remains the tenant and security
boundary; selecting a project focuses project-owned lists rather than creating another tenant.
Creating a workstream requires a project slug, so if you're driving Erdo headlessly and don't have
one yet, create it first. Projects are referenced by **slug**, and project membership is managed in
the app (there's no programmatic member surface). Listing and creating projects is available on all
three surfaces:

```bash theme={null}
erdo project list
erdo project create --slug acme --name "Acme" --description "Acme growth work"
```

The MCP tools are `erdo_list_projects` and `erdo_create_project`; the REST mirrors are
`GET /v1/projects` and `POST /v1/projects` (body: `name`, `slug`, optional `description`).

## Arming the loop, the ledger, and resources

A workstream can be driven entirely by hand, or handed to Erdo's reconciliation loop to run on its
own cadence. **Arming** attaches that loop to one workstream with a **budget envelope** — a token
spend cap and a daily escalation cap — so autonomous work can never spend or interrupt past a limit
you set. Nothing runs autonomously until you arm it; how much the loop may change live,
customer-facing state on its own is a separate control, the [autonomy mode](/autonomy). Set the
budget envelope on the workstream state (`token_budget_millicents`, `escalation_budget_per_day`)
before or while arming.

The **ledger** is the loop's single source of truth, read in one call: the budget envelope, the
workstream's experiments and their recent observations, the [judge calibration](/judges) record and
trust dial, your steering notes, open [attention items](/attention), and the allocator's current
recommendation. **Attaching a resource** records that a page, dataset, experiment, job, thread, or
another workstream belongs to this workstream in a named role (its output, an input, evidence,
something it monitors), so the ledger and event log show the full shape of the work.

## Programmatic access

You can also create, drive, and observe Workstreams over **MCP**, the **REST API**, or the **CLI**
— the same surface an agent uses internally. Everything is **org-scoped and RBAC'd** (read needs
project *view*, writes need *contribute*), and Workstreams are referenced by **slug**, never UUID.

<Note>
  Workstreams (and the surfaces built on them — [Experiments](/experiments),
  [Engine autonomy](/autonomy), the [Attention feed](/attention)) are rolling out gradually. Until
  they're enabled for your workspace, these endpoints and tools return `permission_denied`
  ("workstreams are not enabled for this organization") — contact us to get switched on.
</Note>

### CLI

```bash theme={null}
# list / inspect
erdo workstream list                       # workstreams in the active request context
erdo workstream list --status active blocked
erdo workstream get acme-lead-engine-2026-06

# create
erdo workstream create \
  --project acme \
  --slug acme-lead-engine-2026-06 \
  --title "Acme lead engine" \
  --description "Stand up the Acme outbound lead engine"

# drive
erdo workstream phase-add acme-lead-engine-2026-06 --phase-slug brand-brief --title "Brand brief"
erdo workstream log acme-lead-engine-2026-06 "Landing pages live, monitoring conversions"
erdo workstream set-state acme-lead-engine-2026-06 --status awaiting_user --description "Awaiting brand sign-off"
erdo workstream events acme-lead-engine-2026-06 --limit 50

# set the budget envelope (token cap + daily escalation cap)
erdo workstream set-state acme-lead-engine-2026-06 --token-budget 500000 --escalation-budget 5

# arm the reconciliation loop (recurring allocator pass) with an envelope
erdo workstream arm acme-lead-engine-2026-06 --interval 60 --token-budget 500000 --escalation-budget 5

# read the whole ledger in one call
erdo workstream ledger acme-lead-engine-2026-06 --observations 20

# attach a resource in a named role
erdo workstream attach acme-lead-engine-2026-06 --type page --id <uuid> --rel output
```

`arm` accepts `--interval <min>`, `--model <id>`, and `--timezone <tz>`; the `--token-budget`
(millicents) and `--escalation-budget` (per day) flags set the workstream's envelope via the state
update first, then arm. `attach --type` is one of `page`, `dataset`, `heartbeat`, `experiment_run`,
`thread`, `job`, `knowledge_object`, `approval`, or `workstream`, and `--rel` is the relationship
(`output`, `input`, `evidence`, `monitoring`, `subject`, `parent`, `child`, `running`), with optional
`--title` and `--phase`.

The CLI authenticates with your Erdo token and the active organization (`erdo login`,
`erdo org`).

### MCP tools

| Tool                              | What it does                                                                                                                                                                  |
| --------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `erdo_list_workstreams`           | List your org's workstreams (optionally filtered by status).                                                                                                                  |
| `erdo_get_workstream`             | One workstream by slug — status, phases, resources, recent log.                                                                                                               |
| `erdo_create_workstream`          | Start a workstream in a project (by `project_slug`).                                                                                                                          |
| `erdo_add_workstream_phase`       | Append a new phase to an existing workstream.                                                                                                                                 |
| `erdo_update_work_state`          | Update overall status, title, description, per-phase status, autonomy mode, or the budget envelope (`token_budget_millicents`, `escalation_budget_per_day`).                  |
| `erdo_append_workstream_event`    | Append one line to the event log.                                                                                                                                             |
| `erdo_list_workstream_events`     | Read the full event log (paginated, newest first).                                                                                                                            |
| `erdo_arm_workstream_loop`        | Arm the reconciliation loop on a workstream — a recurring allocator pass on a cadence, within its budget envelope.                                                            |
| `erdo_read_workstream_ledger`     | Read the ledger in one call — envelope, experiments + observations, judge calibration, steering notes, attention items, allocator recommendation, and direct child portfolio. |
| `erdo_attach_workstream_resource` | Attach a page, dataset, experiment, job, thread, or another workstream to the workstream in a named role.                                                                     |
| `erdo_list_projects`              | List the projects you can access.                                                                                                                                             |
| `erdo_create_project`             | Create a project (workstreams need one).                                                                                                                                      |

Identity and RBAC ride the request context, so a caller can only reach their own org's work.

### REST

Base URL `https://api.erdo.ai`. Authenticate with `Authorization: Bearer <token>` and select the
org with `X-Organization-ID`.

| Method  | Path                              |
| ------- | --------------------------------- |
| `GET`   | `/v1/workstreams`                 |
| `GET`   | `/v1/workstreams/:slug`           |
| `POST`  | `/v1/workstreams`                 |
| `POST`  | `/v1/workstreams/:slug/phases`    |
| `PATCH` | `/v1/workstreams/:slug/state`     |
| `POST`  | `/v1/workstreams/:slug/events`    |
| `GET`   | `/v1/workstreams/:slug/events`    |
| `POST`  | `/v1/workstreams/:slug/arm`       |
| `GET`   | `/v1/workstreams/:slug/ledger`    |
| `POST`  | `/v1/workstreams/:slug/resources` |
| `GET`   | `/v1/projects`                    |
| `POST`  | `/v1/projects`                    |

`POST /v1/workstreams/:slug/arm` takes optional `interval_minutes`, `model`, and `timezone` (set the
budget envelope on the state first with `PATCH /v1/workstreams/:slug/state`).
`GET /v1/workstreams/:slug/ledger` takes optional `observations_per_experiment`.
`POST /v1/workstreams/:slug/resources` takes the resource `type`, `id`, relationship `rel`, and
optional `title` and `phase`.
