Use when executing a task the orchestrator dispatched — reads the task and its orchestrator response from the work ledger, loads task-level skills, implements against acceptance criteria, records divergences and the completion report as task sections, and closes the attempt. Triggers on task execution within the implement-feature loop or when an agent picks up a specific task from a plan.
Installs into .claude/skills of the current project.
Are you the author of Start Task?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/jamie-bitflight-start-task)
---
name: start-task
description: Use when executing a task the orchestrator dispatched — reads the task and its orchestrator response from the work ledger, loads task-level skills, implements against acceptance criteria, records divergences and the completion report as task sections, and closes the attempt. Triggers on task execution within the implement-feature loop or when an agent picks up a specific task from a plan.
argument-hint: <plan-address> [--task <task-id>] [--attempt <n>] [--complete <task-id>]
user-invocable: true
---
# Start Task (SAM Task Execution Helper)
You are implementing a specific task in a SAM plan, addressed as `P{id}/T{id}`. The backend resolves that address and returns the task — no path is involved.
Use the SAM CLI's `plan` group for the runner sequence. When your dispatch names an attempt,
read [the runner contract](../../docs/work-ledger/runner-contract.md) in full before the first
ledger command; it owns attempt identity, leases, reports, outcome selection, closure and
refusals. Load `dh:subagent-contract` before returning your response; it owns the response
destination and the distinction between recorded closure, durable outcome and immediate status.
<task_input>
$ARGUMENTS
</task_input>
Load `dh:dh-cli-usage` before using `<sam_cli/>` or `<dh_scripts/>` below.
---
**Tool availability**: task state moves through `<sam_cli/>`, which needs no MCP server. The
artifact and backlog steps below use `mcp__plugin_dh_backlog__*` tools; if one is unavailable, load
`dh:dh-cli-usage` and follow its MCP connection check.
## Parse Arguments
- `plan_address` (required): plan address in `P{hex}` form, e.g. `Pdec8934d`
- `--task <id>` (optional): Task ID to start (defaults to first ready task)
- `--attempt <n>` (optional): the attempt number the orchestrator opened for this dispatch. Carry
it on every ledger command below. It is the key that proves a command belongs to this dispatch:
a command from a superseded attempt is refused with `stale-attempt`.
- `--complete <id>` (optional): Task ID to close
---
## If `--complete <task-id>` Provided
With an attempt number, follow the runner contract's outcome selection, report prerequisites
and closure steps for that attempt. `--complete` names the task to close; select its result from
what happened rather than treating this argument as proof of success.
Without an attempt number, no runner is closing anything, so move the status directly and say why:
```bash
<sam_cli/> plan state \
--address P{N}/T{M} --new-status=complete --reason "{why this moved without a runner}"
```
`--reason` is required — the ledger records why a status moved with no runner behind it.
---
## Starting a Task
1. Read the task via the SAM CLI, naming your attempt. This is your first command:
```bash
<sam_cli/> plan read --address P{N}/T{M} --attempt {n}
```
Naming the attempt also pushes out your lease, so the orchestrator can tell a working runner
from a stalled one. Leave `--attempt` off only when your dispatch named no attempt number.
The result carries the task row — title, requirements, constraints, acceptance criteria,
verification steps, and the `skills` list to load before implementing — and the sections
recorded on the task. Two of those sections decide what you do first:
- `Orchestrator Response` — why a previous attempt was sent back. Act on it before anything
else.
- `Completion Report` from an earlier attempt — when it carries a `BRANCH:` line, switch to
that branch before you start.
Use the address form `P{N}/T{M}` where `N` is the plan number and `M` is the task number from the `--task` argument.
1a. **Discover plan artifacts via manifest** (when issue number is known):
If the task row carries a `github_issue` value or the plan carries an `issue` field, query the artifact manifest to discover available plan artifacts:
```bash
<sam_cli/> artifact list --item-id N
```
If the response contains artifacts (non-empty `artifacts` list), use `artifact_read` to fetch the architect spec and feature context content:
```bash
<sam_cli/> artifact read --item-id N --artifact-type architect
<sam_cli/> artifact read --item-id N --artifact-type feature-context
```
Use the returned content as context for implementation instead of reading filesystem paths directly. This is especially important for worktree-isolated agents that cannot access uncommitted plan files from the root worktree.
**Fallback**: If `artifact_list` returns an empty manifest (no `artifacts` entries) or an error, try `artifact_read` with types `architect` and `feature-context` directly. These artifact types are registered by the agents that produce them.
2. Select the task:
- If `--task` provided, use that ID
- Else run `plan ready --plan-address P{N}` and take the first task it lists — readiness is derived from status and dependencies, so the ledger answers this rather than you
2a. **Load task-level skills** (if present):
- Read `skills` from the task row of the `plan read` result (an array of skill names).
- If absent or empty, skip.
- For each skill name, invoke: `Skill(skill="{skill-name}")`
- If a skill fails to load, log a warning and continue. Do not abort task execution.
- Task-level skills are **additive** to any skills already declared in the agent definition's frontmatter.
3. Your attempt is already open.
`dispatch` opened it when the orchestrator launched you, which is what set the task
`in-progress` and started the lease. There is nothing to claim, and nothing to write to the
status field by hand.
The CLI's `plan claim` command does not reach the ledger. It writes to the content store, so a
task claimed that way leaves the ledger row exactly where it was and the orchestrator watching a
task that never moved. Use `plan read --attempt {n}` (step 1) as your first command instead.
Handle refusals under the runner contract's code table and authority boundary. A superseded
attempt is not yours to rejoin.
4. Register the active-task context via the SAM CLI (required for hook-driven updates):
```bash
<sam_cli/> active-task set \
--address P{N}/T{M} \
--parent-issue N \
--session-id "${CLAUDE_CODE_SESSION_ID}"
```
This is session-scoped context for the PostToolUse hook, which stamps `last-activity` on the
task while you work. It is not task state and holds nothing the ledger holds.
It is not how the SubagentStop hook finds you. That hook takes your address and attempt from
your own launch prompt, because this record is keyed by `${CLAUDE_CODE_SESSION_ID}` — the
parent session's id inside a sub-agent, so a wave's workers all share one — and carries no
attempt number.
Omit `--parent-issue` if the story issue number is not known; absence is `None`. It accepts
`str | int` — GitHub integer IDs (e.g., `42`) and beads string IDs (e.g., `"bd-a3f8"`) are both
valid.
4a. **Renew the lease before work that may outrun it.**
Your lease has a deadline. Before starting anything long — a full test suite, a build, a large
refactor — push it out:
```bash
<sam_cli/> plan renew --address P{N}/T{M} --attempt {n}
```
`renew` prints `renew_by`: the instant the lease next expires. `plan read` and `plan update`
push the deadline out too whenever you pass `--attempt`, but `renew` is the command that tells
you where the new deadline sits. A lease left to expire lets the orchestrator take the task back
and hand it to another runner, and your commands then answer `stale-attempt`.
5. **Record divergence observations during implementation.**
While implementing, if you discover that the architect spec or feature-context
describes something that does not match what you are implementing, record a
divergence note on the task through the ledger.
**When to record**: Record a divergence note when ALL of these hold:
- You are implementing something that differs from what the architect spec or
feature-context describes
- The difference is not a trivial implementation detail (e.g., different variable
name, different import path)
- The difference affects the observable behavior, structure, or scope of the feature
Write the note and its running count in one command. Appending the section and setting the
count are sub-operations of a single `update`:
```bash
<sam_cli/> plan update \
--plan-address P{N} --task-id T{M} --attempt {n} \
--append-section "Divergence Notes" --section-content "{note body}" \
--set divergence_notes={new_count}
```
`{new_count}` is the task's current `divergence_notes` value plus one; read the current value
from the `plan read` result of step 1. Write the field name with an underscore —
`divergence_notes` is the ledger column, and a hyphenated name is refused.
The `--append-section` value supplies the `## Divergence Notes` heading — `{note body}` carries
no heading of its own:
````markdown
### DN-1: {Brief title}
- Plan artifact: `artifact_read(item_id={N}, artifact_type="architect")`, section "{section name}"
- Plan claim: "{quoted text from plan artifact}"
- Actual implementation: "{what was actually done and why}"
- Classification: design-refinement | intent-divergence
- Recorded: {ISO timestamp}
````
Never record a divergence note by editing a file. The task is addressed logically; on a remote
backend no task file exists to edit, and a file written in one worktree is unreadable from
another, so a file-based note is silently lost.
For full artifact classification rules and divergence thresholds, see
[plan-artifact-lifecycle.md](../../docs/plan-artifact-lifecycle.md).
6. **Commit message restriction — Fixes #N trailers are PROHIBITED in task-level commits.**
Task-level commits must NEVER include `Fixes #N`, `Closes #N`, or `Resolves #N` trailers.
These trailers trigger automatic GitHub issue closure. Issue closure is handled exclusively
by `/complete-implementation` in its final commit step, after all quality gates pass.
Including these trailers in task commits causes premature issue closure before verification
is complete.
7. Implement against the task acceptance criteria and run its verification steps.
---
## Close the Attempt
Follow the runner contract's completion steps for the attempt named by your dispatch. Return
your response under `dh:subagent-contract` after closure or a refusal that prevents it.