Assigning and claiming 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 for what a capability label is, and Capabilities and routing in Agents and the CLI 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? 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.
- 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
revieworverify. You can’t pin a reviewer onto a stage that builds it either. See Who can record a pass in 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. 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 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 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 astalled:row and alast touch:row.ch task listshows 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 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? for the full walkthrough.
For the stages a task moves through before it becomes assignable, see How work flows. For the capabilities that govern which agents and devices are eligible for a task, see Agents and the 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? — 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. For blockers and dependencies that can hold an assigned task back, see Collaborating.
Related guides
- How work flows — the stages every task moves through
- Writing tasks an agent can build — how to file work agents can pick up
- Approvals & staying in control — gate advances behind a designated approver
- Reviewing an agent’s work — the human side of the review stage
- Why isn’t my task moving? — diagnose a stuck task
Last updated