/taskwarrior:task-claim
Take ownership of a pending task. Stamps the task with this agent's identity and marks it +ACTIVE so concurrent agents see it is in flight and /taskwarrior:task-coordinate skips it on the next wave.
When to Use This Skill
| Use this skill when... | Use a sibling skill instead when... |
|---|---|
Starting work on a task surfaced by /taskwarrior:task-coordinate |
Filing a brand-new task — use /taskwarrior:task-add |
Resuming a task after a context break (re-stamps started time) |
Pausing for handoff without closing — use /taskwarrior:task-release |
Forcing a stale claim onto yourself with --force |
The task is done and ready to land — use /taskwarrior:task-done |
Context
- Task CLI available: !
task --version - Git repo detected: !
find . -maxdepth 1 -name '.git' -print -quit - Hostname: !
hostname - Existing UDAs: !
task _udas
Git probes (git rev-parse --show-toplevel, git branch --show-current)
write to stderr in a no-git cwd, and stderr from a Context backtick
aborts the skill before its body runs. Git toplevel and current-branch
resolution are done in the body via the Bash tool (where
2>/dev/null and exit-code handling are tolerated).
Parameters
Parse $ARGUMENTS:
$0— task ID (required).--no-coworker-marker— skip the/git:coworker-check --claimstep (use when the repo is intentionally shared and another agent will claim its own scope).--force— claim even when the task is already+ACTIVE(the previous claim is overwritten with an annotation noting the takeover).
Execution
Execute this claim workflow:
Step 1: Ensure identity UDAs exist
The identity UDAs (agent / pid / host / branch / worktree) are part of
the canonical set in the shared ensure-udas.sh script. Check for missing UDAs:
bash "${CLAUDE_SKILL_DIR}/../../scripts/ensure-udas.sh" --check
If it reports UDAS_MISSING greater than 0, confirm with the user (declarations
persist in ~/.taskrc) and install — the script is idempotent and installs the
full linkage + identity set in one pass:
bash "${CLAUDE_SKILL_DIR}/../../scripts/ensure-udas.sh"
Step 2: Load the task and check active state
task "$TASKID" export | jq '.[0] | {id, uuid, description, status, start, agent, pid, host, branch, worktree}'
Use export | jq — never task <id> info or task <id> list (both exit 1 on empty / closed tasks and cancel parallel siblings; see .claude/rules/parallel-safe-queries.md).
Capture the uuid field as $TASK_UUID — every mutating call from Step 3
onward addresses the task by $TASK_UUID, never $TASKID. $TASKID may be a
numeric ID that renumbers if another agent closes an unrelated task during the
coworker-check pause in Step 3; $TASK_UUID does not (see
.claude/rules/task-id-stability.md).
Read the JSON. Decide:
| Condition | Action |
|---|---|
status is not pending |
Abort. Tasks must be pending to claim. |
start is set and --force not passed |
Abort. Report current agent / pid / host / branch so the user can either --force or pick another task. |
start is set and --force passed |
Annotate with takeover notice (Step 6) and proceed. |
start is unset |
Proceed cleanly. |
Read a task's annotations before working it
task list truncates them, hiding what past sessions established:
task <uuid> export | jq -r '.[0].annotations[].description'. 2026-08: a
session re-derived and announced a finding task 48517b52 already held.
Step 3: Coworker-check claim (default on)
Unless --no-coworker-marker was passed, write the session marker so destructive git ops in this clone (stash, reset, checkout --) trigger the cross-agent guard:
Use SlashCommand to invoke `/git:coworker-check --claim`.
The git-side marker (<git-dir>/.claude-session-<pid>) and the taskwarrior +ACTIVE claim are independent signals. Together they reinforce: a stash hook can read either one, and either is enough to pause a destructive op.
If the SlashCommand tool is unavailable in the current session, fall back to running the script directly:
bash "$(git rev-parse --show-toplevel)/git-plugin/skills/git-coworker-check/scripts/claim-session.sh" --project-dir "$(pwd)"
Step 4: Resolve identity values
Capture once and reuse across the next two steps:
| Value | Source |
|---|---|
AGENT |
claude-${CLAUDE_SESSION_ID:0:8} (short, stable for the session) |
PID |
$$ (the bash subshell PID — sufficient to cross-link with the git marker since both are taken at the same moment) |
HOST |
hostname |
BRANCH |
git branch --show-current (may be empty on a detached HEAD — leave the UDA unset rather than writing the literal "HEAD") |
WORKTREE |
git rev-parse --show-toplevel |
Step 5: Start the task and stamp identity
Two calls — start first so +ACTIVE is set even if the modify step fails:
task "$TASK_UUID" start
task "$TASK_UUID" modify \
agent:"$AGENT" \
pid:"$PID" \
host:"$HOST" \
branch:"$BRANCH" \
worktree:"$WORKTREE"
Omit branch: when BRANCH is empty (detached HEAD). Quote every value — worktree: paths frequently contain spaces.
Step 6: Annotate the claim
task "$TASK_UUID" annotate "claimed by $AGENT (pid $PID) on $BRANCH from $HOST:$WORKTREE"
When --force is used over an existing claim, annotate the takeover separately first so the previous owner's identity is preserved in the audit trail:
task "$TASK_UUID" annotate "force-claim by $AGENT — previous: agent=$PREV_AGENT pid=$PREV_PID host=$PREV_HOST"
Step 7: Report
Print:
- Task ID, description, urgency
- Identity stamp:
agent/pid/host/branch/worktree - Coworker-check status: claim written / skipped
- Suggested next step:
- implementation work
/taskwarrior:task-release <id>to hand off without closing/taskwarrior:task-done <id>once the work has landed
Agentic Optimizations
| Context | Command |
|---|---|
| Active filter (parallel-safe) | task +ACTIVE export | jq '.[] | {id, agent, branch, host}' |
| Single-field DOM read | task _get "$TASKID".agent (exit 0 even when unset) |
| Cross-project active scan | task status:pending +ACTIVE export | jq |
| Stale-claim probe | task +ACTIVE start.before:now-4h export | jq |
| Skip empty-result failures | Always export | jq, never task active list |
Quick Reference
| Field | Type | Source on claim |
|---|---|---|
agent |
string | claude-${CLAUDE_SESSION_ID:0:8} |
pid |
numeric | $$ at claim time |
host |
string | hostname |
branch |
string | git branch --show-current (omit on detached HEAD) |
worktree |
string | git rev-parse --show-toplevel |
start (built-in) |
date | Set automatically by task start; cleared by task stop |
| Tag (virtual) | Set by | Cleared by |
|---|---|---|
+ACTIVE |
task start |
task stop / task done |
Related
/taskwarrior:task-coordinate— surfaces unblocked candidates to claim/taskwarrior:task-release— release without closing (handoff)/taskwarrior:task-done— close after landing (auto-releases the claim)/git:coworker-check— sister signal: process-scan + session marker.claude/rules/agent-coworker-detection.md— combined-signal rationale.claude/rules/parallel-safe-queries.md—export | jqidiom.claude/rules/task-id-stability.md— why this skill resolves$TASK_UUIDonce and mutates by UUID