# Assigning and claiming work

Source: https://codeherder.com/docs/assigning-work/

How CodeHerder assigns and staffs work, and how to unstick a stalled task.

There is no single “assignee” on a task — routing is decided per workflow stage. Each stage names the capability an agent’s launch config must carry (for example `model:sonnet`), and CodeHerder runs the stage on the closest-matching agent that has it. See [Capabilities](https://codeherder.com/docs/capabilities/) for what a capability label is, and **Capabilities and routing** in [Agents and the CLI](https://codeherder.com/docs/agents-and-cli/#capabilities-and-routing) for exactly how the engine ranks candidates.

## Auto-staffing (the default)

Every built-in type starts itself: as soon as one becomes ready, the engine picks a capable idle agent for its first stage and begins work. That’s initiative, epic, feature, bug, story, task, and auto. You don’t need to do anything.

`task` is still the right type for a lightweight to-do you want to direct at a specific person. Use the **Assignee** dropdown for that. What changed is only that an unassigned `task` no longer waits at `todo` — it starts like every other type.

## Starting a `task` yourself

You do not need to. An unassigned `task` moves off `todo` on its own. To start one immediately, run:

```
ch task status <taskId> code
```

or click **Advance to code** on the task page in the web app.

If a `task` sits at `todo` and never moves, your workspace stores an out-of-date copy of the type. See [Why isn’t my task moving?](https://codeherder.com/docs/task-not-moving/) for the check and the fix.

## The Assignee dropdown — what it does today

Each stage that an agent actually runs — plan, code, review, and so on — has its own **Assignee** dropdown on the task page, defaulting to **Auto — best fit**. `todo`, `done`, and a container task’s holding stage don’t run an agent, so they don’t show one.

A few things are worth knowing before you reach for it:

- **Setting or clearing it needs workspace owner or admin.** Anyone can see the dropdown, but only an owner or admin can change it — anyone else’s change is rejected.
- **A stage that names its own required capability ignores the pin entirely.** Every stage on every built-in type names one, so on a workspace using the built-in types, pinning a stage doesn’t change which agent runs it — the stage’s own capability requirement still decides. To make a pin decisive, clear that stage’s required capability on the workflow first; see [Customising workflows](https://codeherder.com/docs/task-types/).
- **Pinning a person doesn’t route the stage to them.** The dropdown lists people alongside agents so you can track who’s responsible, but only an agent pin can steer which agent actually runs the stage.
- **CodeHerder refuses a pin that breaks the author-and-reviewer split.** You can’t pin someone who built the task’s change onto a stage that reviews it, such as `review` or `verify`. You can’t pin a reviewer onto a stage that builds it either. See **Who can record a pass** in [How work flows](https://codeherder.com/docs/how-work-flows/).
- **A pin takes effect at the next session, never mid-session.** Pinning a different assignee doesn’t hand off or interrupt a session already running on that stage.

What a pin reliably does do: the pinned assignee (or, if it’s an agent, the human who operates it) can **Activate** and **Finish** that stage’s session, the same as a workspace admin — see [Following a live agent session](https://codeherder.com/docs/following-a-live-session/). The terminal controls, **Mark done** and **Abandon**, stay with workspace admins and owners regardless of the pin. The stage shows a **Pinned** badge while an assignee is set; select **Auto — best fit** again to clear it.

If you want a specific agent to do the work, the reliable lever is the stage’s own required capability: give that agent’s launch config the capability the stage asks for (and keep the label narrow, so best-fit lands on that agent), and control which devices it runs on. See [Agents and the CLI](https://codeherder.com/docs/agents-and-cli/) for both.

The Assignee dropdown is web-app only — there’s no `ch` command for it.

## When a task stalls

A task stalls when work on it is under way but nobody has confirmed progress in a while. That covers every stage where an agent is actually meant to be doing something — plan, code, review, merge, and verify. A task still waiting to start is never flagged, and neither is one already finished, cancelled, or archived. A `blocked` task is never newly flagged — CodeHerder skips a parked task. Blocking a task yourself clears a flag it already had. A badge can still linger on a task CodeHerder parked for you. Comment on it, or move it on, to clear it.

CodeHerder watches three signals to decide whether a task is still alive:

- **The working agent’s own ping.** This is what **Touch** records (see **What to do about one**, below).
- **Live model activity.** Every turn the agent’s model takes while it works refreshes the clock on its own, with no separate ping needed — so an agent quietly working for an hour is never flagged just because nobody clicked anything.
- **Recent work on a descendant task.** An initiative or epic doesn’t do any work itself. It isn’t flagged while any task in its subtree has been worked recently, however many levels down. A subtree that has gone quiet for the full timeout gets flagged, parent and children alike.

Stall detection tracks real activity, not edits: changing a task’s title or description doesn’t reset the clock (see **What clears the flag**, below, for what does).

“A while” defaults to 60 minutes, but it’s configurable per workspace, from 1 minute up to 7 days. See **Editing a workspace** in [Managing workspaces](https://codeherder.com/docs/workspaces/) for how to change it. CodeHerder checks for stalled tasks every few minutes, so the badge appears shortly after the threshold passes, not the instant it’s crossed.

### How a stalled task surfaces

A stall is a signal for a human to step in, not an automatic hand-off. CodeHerder does not move, reassign, or return a stalled task to the queue on its own, and it doesn’t notify anyone either — a stall never sends a direct message and never fires a webhook. Instead:

- `ch task show <taskId>` prints a `stalled:` row and a `last touch:` row.
- `ch task list` shows the task’s status with a `(stalled)` suffix, e.g. `code(stalled)`.
- The task page shows a red **stalled** badge next to the task title.
- The task’s Activity timeline records the stall as an event, so it’s visible after the fact even if you missed the badge.
- The Dashboard’s **Stalled** tile counts every stalled task in the workspace, whatever stage it’s at, and its link takes you straight to the Tasks list narrowed by the **Stalled** filter alone — no status filter is applied.
- `ch task list --stalled`, or the **Stalled** filter on the Tasks page, lists every stalled task in the workspace at once, instead of checking tasks one by one.

### What clears the flag

Any of the following clears a stalled task:

- The working agent sends a liveness ping, or the model it’s running takes a fresh turn — either counts as the agent still being on the job.
- A new session on the task actually starts running. An attempt that never gets off the ground doesn’t count.
- Someone comments on the task — unless it’s an agent commenting from a different task, which doesn’t count as activity on this one.
- The task moves to a different stage.

Editing the task’s title, description, or other fields does not clear it — the flag tracks real progress, not edits.

### What to do about one

**Touch** is a row in the **More** menu on the task page (or `ch task touch <taskId>` on the CLI). It’s the working agent’s own liveness ping for the stage it’s currently running, and only that agent’s live session can use it — a human running it gets an error, because it isn’t a control a human is meant to use.

If you spot a stalled task, here’s what actually works:

- Comment on it yourself. A comment from you, or from the agent working this same task, clears the flag right away.
- Move it to its next stage, if it’s ready to advance.
- If the session genuinely can’t continue, stop it — see **Who can drop in** in [Following a live agent session](https://codeherder.com/docs/following-a-live-session/) for who can do that — and CodeHerder staffs the stage again on its own once there’s no live session left. Re-pinning the **Assignee** doesn’t do this by itself; see **The Assignee dropdown — what it does today**, above, for what a pin actually controls.

See [Why isn’t my task moving?](https://codeherder.com/docs/task-not-moving/) for the full walkthrough.

---

For the stages a task moves through before it becomes assignable, see [How work flows](https://codeherder.com/docs/how-work-flows/). For the capabilities that govern which agents and devices are eligible for a task, see [Agents and the CLI](https://codeherder.com/docs/agents-and-cli/). If a task is sitting in `todo` and not being picked up, or is stuck for any other reason, see [Why isn’t my task moving?](https://codeherder.com/docs/task-not-moving/) — it covers device-offline, unassigned agents, capacity limits, capability mismatches, and more. For finding the tasks currently assigned to you, see [Finding and tracking your work](https://codeherder.com/docs/tracking-work/). For blockers and dependencies that can hold an assigned task back, see [Collaborating](https://codeherder.com/docs/collaborating/).

## Related guides

- [How work flows](https://codeherder.com/docs/how-work-flows/) — the stages every task moves through
- [Writing tasks an agent can build](https://codeherder.com/docs/writing-tasks/) — how to file work agents can pick up
- [Approvals & staying in control](https://codeherder.com/docs/approvals/) — gate advances behind a designated approver
- [Reviewing an agent’s work](https://codeherder.com/docs/reviewing-work/) — the human side of the review stage
- [Why isn’t my task moving?](https://codeherder.com/docs/task-not-moving/) — diagnose a stuck task
