CodeHerderSearch⌘KRequest access →

The stage library

Browse and author the shared stages your workflows are built from, and compose a workflow's pipeline from them instead of writing one by hand.

A workflow’s pipeline can be built from stages in your workspace’s shared stage library: reusable definitions of what a stage does, referenced by any workflow composed from the library. A stage carries the prompt an agent gets when it works there, whether it can commit code, which capabilities an agent needs to run it, and its verifications. The workflows your workspace starts with have their pipelines written out directly and don’t draw on the library yet — composing a type’s workflow from it (covered below) is how that starts, and once a type is composed, more than one type can point at the same stage and pick up the same definition.

This page covers the library itself — browsing it, customising a stage, and seeing what depends on one — and how to build a workflow’s pipeline out of library stages instead of writing every stage’s settings by hand. If you just want to reorder or edit a type’s existing pipeline, start with Customising workflows instead; this page is about the shared building blocks underneath it.

You can work with the library either from Settings → Stages in the left sidebar or from the ch CLI. This page mostly shows the CLI, since it’s the fuller surface, but every example below has a web equivalent.

Browsing the library

ch stage list

This lists the library as it resolves for your workspace: your own stages plus every built-in and inherited one, one row per key. Each row shows the stage’s key, label, owner (builtin, workspace, or inherited from <workspace>), whether it’s enabled, its version number, whether it’s agent-writable, and any required capabilities.

CodeHerder ships with a set of built-in stages — code, review, merge, verify, and others named after the stages a typical pipeline has — available for any workflow you compose from the library. Add --disabled to see only the ones you’ve turned off, or --enabled for the reverse — see Listing enabled and disabled records for the shared grammar behind those two flags.

To see one stage in full — its prompt, declared fields, required capabilities, writable setting, container image, and verifications:

ch stage show code

Settings → Stages shows the same list, with a search box and an Enabled / Disabled / All picker in place of --enabled/--disabled. Click any row to open that stage’s own page, which shows everything ch stage show prints.

Customising a stage

A built-in stage is read-only: you can’t edit code or review directly. To change one, create your own entry at the same key. That local entry shadows the built-in for your workspace and everything nested under it — any workflow you compose from that key, now or later, resolves to your version instead.

ch stage create code --stage-file my-code-stage.json

The file is the stage’s document — its label, spec (prompt, writable, required capabilities, image, and so on), and any fields it declares. --change-note records an optional note against the new version.

On a built-in stage’s page in Settings → Stages, the same move is a Customize button, which opens a form for the same document instead of a file.

An inherited stage — one your workspace picked up from a parent — is read-only too, but for a different reason: it’s only editable from the workspace that actually owns it. ch stage list marks it inherited from <workspace> so you know where to go; its page in Settings → Stages shows the same thing and names the workspace to edit it from.

Changing an existing stage

ch stage edit is a sparse patch: send just the key you want to change (label, spec, or fields) and CodeHerder merges it into what’s already there — you don’t have to restate everything. The safe way to build that document is a show → edit → apply round-trip:

ch stage show my_review --json | jq '.data | del(.enabled, .disabled)' > stage.json
# edit stage.json
ch stage edit my_review --stage-file stage.json

show always includes enabled, so strip it before editing — ch stage edit doesn’t accept enabled/disabled at all; use ch stage enable/ch stage disable for that instead, covered below. In Settings → Stages, the equivalent round-trip is a form: open the stage’s page and click Edit.

Saving a stage carries the change straight to every workflow in your workspace that composes a pipeline from it. Every workflow that references my_review is automatically rebuilt with the new version, in the same save — you don’t need to re-apply anything. Two things worth knowing about that:

  • It only reaches workflows owned by your own workspace. If a descendant workspace inherited the stage and built one of its own workflows from it, your save doesn’t touch that workflow — the descendant workspace has to rebuild it there itself.
  • CodeHerder checks the rebuild before it commits to anything. Say your change would break a workflow that references the stage — a route_to the new version no longer declares a matching verification for, for instance. The whole save is refused, nothing is saved (not even the stage itself), and the message names which workflows couldn’t be rebuilt and why. A stage referenced by an unusually large number of workflows is refused outright rather than rebuilding all of them at once. And a workflow whose rebuilt pipeline comes out identical to what it already had gets no new version — nothing changed, so nothing is recorded.

Whenever a write leaves a stage agent-writable or requiring capabilities, CodeHerder prints a note naming ch stage references <key> — on create, edit, enable, and disable alike, regardless of whether that particular write actually changed it. Because saves now propagate, that note is a live warning, not a heads-up for later: every workflow it lists picks up the new writable/capability setting from this same save. The web editor shows the same warning inline, listing the affected workflows, before you click Save.

Want to see the effect before you commit to it? Preview it:

ch stage impact my_review --stage-file stage.json

This runs the exact same check edit would, without saving anything — which workflows would be rebuilt and to what version, which would block the save and why, and which belong to descendant workspaces and will only pick the change up on their own next save. Drop --stage-file to preview the stage exactly as it stands today, which is also a way to check a pending disable before you run it. In Settings → Stages, this preview runs automatically while you edit — no separate command needed.

Seeing who depends on a stage

ch stage references my_review

This lists every workflow whose pipeline currently references the stage, and the instance name each one gave it. Check this before editing a shared stage’s privilege settings, or before disabling one — or use the impact preview above, which shows the same references alongside what a specific change would do to each. Settings → Stages shows the same reference list on a stage’s own page.

Disabling a stage

ch stage disable my_review
ch stage enable my_review

(delete is an alias for disable — CodeHerder never hard-deletes a stage.) Disabling is refused while a workflow still references the stage, and the error lists which ones — clear them out first, or leave the stage enabled. The one exception: if your key also shadows a built-in, disabling it is allowed, because the key still resolves — it just falls back to the built-in’s definition, so nothing referencing it is left dangling.

Version history

ch stage versions my_review
ch stage versions my_review --version 2

Every save adds a new version, with a timestamp, who made it, and any change note. Add --limit and --cursor to page through a long history. History only exists for a stage your workspace authored itself. Run this against a built-in or an inherited key and CodeHerder tells you it isn’t owned here — for an inherited key, check ch stage list to see which workspace it’s inherited from and ask there; a built-in has no owning workspace and no version history to look up anywhere. A workspace-owned stage’s page in Settings → Stages shows the same Version history list.

There’s no revert for a stage — to go back, open the old version and save its content again as a fresh edit. See Version history and going back for how that compares with the other things CodeHerder keeps a history of.

Composing a workflow from the library

A workflow’s pipeline doesn’t have to be written out stage-setting by stage-setting. Instead, you can define it as an ordered list of instances, each pointing at a library stage:

ch workspace workflow edit hotfix --from-file composition.json

composition.json looks like this — the same file the edit command already accepts, just with a top-level instances list instead of a flattened schema:

{
  "key": "hotfix",
  "label": "Hotfix",
  "instances": [
    { "name": "todo", "stage": "todo", "class": "todo" },
    { "name": "quick_fix", "stage": "code", "class": "doing", "to": ["double_check"] },
    { "name": "double_check", "stage": "review", "class": "doing", "to": ["done", "quick_fix"] },
    { "name": "done", "stage": "done", "class": "done", "terminal": "success" }
  ]
}

Each instance’s name is the stage name the task actually sits in (what shows up in ch task status); its stage is the library key supplying that instance’s content — its prompt, whether it’s writable, and so on. They don’t have to match: quick_fix above gets its content from the code stage, and double_check from review. That’s also how two instances in the same pipeline can reuse one stage under two different names.

class, to, terminal, and a verification’s route_to — plus gate, escalate_after_failures, and max_reject_loops for a reject loop, and an optional skills list narrowing that instance’s own sessions (see Which skills a stage gets) — stay per-instance, because they describe how this workflow uses a stage, not the stage’s own shared definition; the same stage can be a plain forward step in one type and a reject-loop target in another.

CodeHerder checks a composition document in this order, and reports the first problem it finds:

  1. Two instances can’t share a name.
  2. Every instance’s stage has to resolve to a stage in your library — and to an enabled one; a key that only matches a disabled entry is treated the same as a missing one.
  3. A route_to on a verification has to name a verification the resolved stage actually declares.
  4. A max_reject_loops cap is rejected if nothing ever routes back to that instance — there’d be nothing for it to cap.

Once it’s applied, ch workspace workflow show prints the type’s pipeline back with each instance annotated by the stage and owner it came from, under instances (composed from the stage library).

If you’d rather write the flattened schema by hand instead — every stage’s settings spelled out directly, the way Customising workflows describes — --from-file still accepts that format too. Use whichever fits how you think about the type; CodeHerder tells the two apart by whether the file’s top level has instances or stages. A file with both is rejected, so it doesn’t have to guess which one you meant.

In Settings → Workflows, a type’s Stages section lets you build the same kind of pipeline: add instances that each point at a library stage, instead of authoring every setting by hand. An existing flattened type doesn’t switch over on its own — click Convert to composition… on its editor first. It tells you up front what that changes (each stage’s content will come from the library stage you pick, replacing what was stored on the type directly) before anything is actually written.

An admin composing a type’s pipeline this way isn’t the only place a composition happens. An auto task’s own agent selects and orders stages from this same library at run time, for that one task — see Auto tasks — the agent chooses the workflow. Either way, a workspace’s composition policy (a floor of required stages, a ceiling on model tiers, or both) applies the same checks to what comes out.

Who can do what

Anyone in the workspace — human or agent — can read the library: list, show, versions, and references are all open to any member.

Previewing a change with ch stage impact (or the web editor’s live preview while you edit) needs a workspace owner or admin, the same as making the change would — but not necessarily a person. It saves nothing, so an agent with that role can run it too.

Actually writing to the library is narrower still. create, edit, enable, and disable need a workspace owner or admin, and they have to be a person — an agent’s own credentials are refused, even for an agent with an admin role. Writing also requires the Starter plan or above, the same plan floor as customising a workflow.

Settings → Stages carries the same rules: anyone can browse, but the create/edit/disable controls only appear active for an owner or admin — everyone else sees a read-only view with a note explaining why.

CodeHerder

Round up your herd.

Bring every human and every agent onto one table. Watch the work move. Costs update as it happens.

Try "pricing", "connect a device", or "who reviews the code"

↑↓ move · ↵ open · esc close