CodeHerderSearch⌘KRequest access →

Capabilities

What a capability label is, and the places it controls routing and requirements.

The word “capability” shows up in several places in CodeHerder — on agents, on launch configs, on workflow stages, and on tasks and schedules — and the one rule underneath all of them is: capabilities is what a thing HAS; a “required capabilities” field is what a thing NEEDS. Agents, launch configs, and devices all carry a capabilities set (what they can do); tasks, schedules, and workflow stages carry a required-capabilities set (what they need). This page is the single place to check which rule applies where.

What a capability is

A capability is a short, free-form label string. You choose the labels to match your own conventions — common examples are go, frontend, or op.review. One convention is built in: model:<tier>, where the tier is haiku, sonnet, or opus, in increasing order of capability and cost. Use model:<tier> labels to describe which AI model an agent should run, and plain skill labels for anything else you want to track. For the rest of the model story — naming an exact model, restricting a config to an Allowed models list, and cost-aware routing — see Which model your agents run.

The two questions capabilities answer

Every place capabilities appear is answering one of two questions, with one exception covered below:

  • What can this agent do? — a capability declared on an agent or a launch config, describing a skill it carries.
  • What does this work need? — a capability declared on a task, a schedule, or a workflow stage, describing a requirement.

The rule that matters is this: skill labels on an agent only ever rank — everything else, including a task’s or a schedule’s own required capabilities, is a hard gate. The sections below walk through each place in turn; the table at the end summarizes all of them.

Agent skill labels — soft

Set with ch agent create --cap <label> (repeat the flag for more than one), or edit afterward. These are the skill labels shown on the agent itself.

ch agent create --display-name "Go coder" --cap model:sonnet --cap go

When the engine auto-staffs an unassigned task, it ranks available agents by how much their skill labels overlap with the task’s required capabilities — more overlap means higher priority. A partial or even zero overlap never blocks placement: the task still runs on the best available agent, even a plain skill miss. Skill labels are a ranking signal only.

Launch-config capabilities — hard

Set with ch agent config edit <agent-id> --cap <label> (or ch agent config create for an additional config). This is a different set of labels, stored on the agent’s launch config, not on the agent itself — a SUPPLY set, exactly like the agent’s own skill labels above, just scoped to what this one config can run. Passing --cap replaces the config’s whole capability list rather than adding to it, so include every capability you want the config to keep on that call — every other field on the config (command, args, environment, persona, and so on) stays as it was, since config edit only changes the flags you actually pass:

ch agent config edit <agent-id> --harness claude --cap model:opus --cap model:sonnet

You can set this same list when you create the agent, in the same call — spelled --config-cap there instead of --cap, since ch agent create already uses --cap for the agent’s own skill labels above:

ch agent create --display-name "Builder" --harness claude --config-cap model:opus --config-cap model:sonnet

See Creating a runnable agent in one call for the full flag set this unlocks.

The engine runs a workflow stage only on a launch config whose capabilities fully cover what that stage requires. If no launch config in your workspace carries a capability a stage requires, that stage is unstaffable — any task reaching it queues indefinitely, with no agent ever picking it up. This is a hard gate, not a preference.

Covering a whole workflow. Different stages of a workflow can require different capabilities — the built-in feature, story, and bug types need both the model:opus and model:sonnet tiers across their stages. A single launch config needs every tier the workflow uses to carry a task through it end to end; split across configs (one per tier) works too, since the engine picks whichever enabled config covers a given stage. See Agents and the CLI for the setup walkthrough.

For the full walkthrough of launch configs — including multiple configs per agent and how the engine picks between them — see Agents and the CLI.

Stage required capabilities — hard

Set on the stage’s own content — the shared library stage for a composed workflow, which every built-in type is, or the type’s own schema for a hand-written one, edited through the CLI. For a composed workflow the editor shows the list read-only, alongside a link to edit it at the library stage. A stage’s required capabilities are the list a launch config must fully cover before the engine will run that stage on it — the other side of the launch-config gate above. See Customising workflows for the full explanation of where each kind of workflow keeps this setting.

Agent device requirements — hard

Set with ch agent edit <agent> --device-requirement <token> (repeat for more than one), or --clear-device-requirements to remove them all. This is a fifth place capabilities appear, and it answers a different question from the other four: not “which work should this agent get” but which machine is this agent allowed to run on at all — hard, like the launch-config and stage gates above.

ch agent edit "Builder" --device-requirement bin:claude

CodeHerder only places a session for this agent on a device that reports every token the agent requires — a device missing one is skipped for that agent’s work entirely, the same hard-gate behaviour as a launch-config capability. See Editing an agent for the full agent edit flag set.

Task and schedule required capabilities — hard

Set with ch task create --cap <label> or ch schedule create --cap <label> (repeat for more than one). These describe what the task, or the tasks a schedule creates, actually needs.

ch task create --title "Write Go migration" --type story --cap go --cap model:opus

This is a hard gate, not a ranking signal: only an agent whose launch config covers every one of these capabilities can ever run the task, and the set is combined with each workflow stage’s own required capabilities as the task moves through it. A capability no launch config in your workspace covers strands the task at that stage indefinitely — there is no fallback to “best available agent” the way there is for agent skill labels. See Writing tasks an agent can build for the rest of task creation.

Two different passes over the same labels. It’s easy to conflate this with agent skill labels above because both compare a task’s required capabilities against an agent’s, but they run at different times for different reasons. First, when the engine is deciding which agent to auto-staff onto an unassigned task, it ranks candidates by skill-label overlap — that pass is soft, and zero overlap never blocks it. Separately, once an agent is about to actually run a stage, the engine checks whether that agent’s launch config covers every required capability — that pass is hard, and a miss refuses to start the stage at all. A task can clear the first pass (get assigned to an agent) and still stall forever at the second.

Repairing a stranded task. If a task was created with a capability typo’d or no longer covered by any launch config, fix it in place rather than recreating it:

ch task edit <taskId> --cap <label>...
ch task edit <taskId> --clear-caps

--cap replaces the task’s whole required-capabilities set; --clear-caps empties it. The two are mutually exclusive on a single call. A schedule works the same way: ch schedule edit <id> --cap <label>... replaces the set, and ch schedule edit <id> --clear-caps empties it. Creating or editing a schedule with a capability set runs the same launch-config coverage check as a task — see the caveats below.

Soft vs. hard, at a glance

Where it’s set Command Effect
Agent ch agent create --cap <label> Soft — ranks agents during auto-staffing; never blocks
Launch config ch agent config edit <agent-id> --cap <label> Hard — a stage only runs on a config whose caps cover its requirements
Workflow stage Library stage for a composed workflow, type schema (CLI) for a hand-written one Hard — the requirement side of the launch-config gate above
Agent device requirement ch agent edit <agent> --device-requirement <token> Hard — restricts which devices the agent’s sessions can be placed on
Task / schedule ch task create --cap <label> / ch schedule create --cap <label> Hard — only a launch config covering every token can run the task; combined with the stage’s own caps

Setting a required capability on a task, or on a launch config, needs the Starter plan — skill labels are free on every plan. See Plans and limits.

When capabilities stall a task

A task that queues without an agent ever picking it up has two possible causes:

  • A stage’s required capabilities go uncovered by any launch config. The web app’s Capability gap callout on the Set up → Agents page lists each stage that no enabled launch config covers, with the capabilities it needs. A task can still stall for the other reason below.
  • The task’s own required capabilities aren’t covered by any launch config. This is checked once up front — creating or editing a task with --cap is rejected outright if no launch config in your workspace covers the set, once your workspace has at least one launch config configured. But that check only looks at the task’s own set: a stage’s required capabilities are combined into the same set as the task moves through the workflow, so a task that passed the check at creation can still stall later once it reaches a stage whose own requirements push the combined set past what any launch config covers.

How you see it. A task carrying required capabilities no launch config can ever satisfy shows a Start refused badge next to its title (task list and task detail) and a Start refusal row on the task detail page, giving the exact reason and how many times the engine has retried; ch task show <taskId> prints the same thing as a start refusal row, and --json carries it as startRefusal.

To fix it, either add the missing capability to a launch config (see Agents and the CLI), or repair the task itself with ch task edit <taskId> --cap <label>... or ch task edit <taskId> --clear-caps.

For the full diagnostic walkthrough, see Why isn’t my task moving?; for reading the Capability gap callout itself, see Monitoring your agents. To see which capability tokens your fleet actually advertises, and which stages are covered because of it, see Staffing coverage.

Last updated

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