Dispatch
The team runs inside a normal Claude Code session — the running claude process becomes the team lead. There is no external launcher and no setup script. Everything flows through the afk-dispatch skill, which self-bootstraps on every dispatch (Step 0 of the playbook).
Self-bootstrap (Step 0 of the skill)
The first thing the lead does on every /afk-dispatch invocation is pre-flight + label bootstrap. All checks are cheap; all mutations are idempotent. Specifically:
- Verifies
claude --version ≥ 2.1.32(Agent Teams landed in 2.1.32). - Verifies
ghis authenticated andjqis installed (theTeammateIdlehook needsjq). - Creates any missing GitHub labels —
AFK(blue),AFK:in-progress(yellow),AFK:done(green) and the rest of theAFK:*family — with an explicit colour, leaving existing labels' metadata untouched. - Confirms
CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1is set in.claude/settings.json. - Sweeps stale
AFK:in-progresslabels off any open issue with no active task in the shared list.
If any of 1–4 fails, the lead stops and tells you exactly what to install or set. There is intentionally no separate bootstrap script — keeping pre-flight inline with the dispatch playbook means a fresh clone can dispatch a team without first running bash.
Invocation
/afk-dispatch <prd-issue-number> # full run
/afk-dispatch <prd-issue-number> --dry-run # print roster + task list, don't spawn
--dry-run output:
=== /afk-dispatch 183: dry run ===
Roster:
- implementer (opus, Edit/Write/Bash/Read/Grep/Glob)
- reviewer (opus, Read/Grep/Glob/Bash — no Edit/Write)
- verifier (opus, Read/Bash)
- researcher (opus, Read/Grep/Glob/WebFetch — spawned on-demand)
Tasks (4 total, in dependency order):
#201 Add /api/smokes endpoint (unblocked)
#202 Wire /api/smokes to frontend list (blocked_by #201)
#203 Add rating column to smokes (unblocked)
#204 Display rating in history (blocked_by #203)
Playbook (what the lead does)
Full version: .claude/skills/afk-dispatch/SKILL.md. Short version:
- Read PRD (
gh issue view <prd>) and openAFK-labeled issues (gh issue list --label AFK --state open). - Spawn implementer, reviewer, verifier as persistent teammates. Spawn researcher on-demand per issue with non-trivial "Interface Changes".
- Populate the shared task list — one task per issue,
blocked_bymirrors each issue's "Blocked by" section. Research tasks block their paired implementation tasks. - Coordinate the flow per issue: researcher memo → implementer claims + codes + stages → reviewer approves → verifier smokes + commits → implementer advances labels + closes issue.
- Handle
BLOCKED(release task to pending) andsmoke FAIL(task stays in-progress; implementer re-iterates). - On empty queue: shut down each teammate, then run team cleanup.
Label flow
AFK → implementer claims, adds AFK:in-progress
AFK:in-progress → reviewer approves + verifier commits
→ implementer removes AFK:in-progress, adds AFK:done
AFK:done → issue closed
Same pattern as Ralph, different label prefix. Do not mix — an issue must not carry both AFK and ralph.
Hooks
Two quality gates attach via the Agent Teams hook surface (registered in .claude/settings.json):
TaskCompleted → task-completed-smoke.sh
Runs when a teammate marks a task completed. Reads the latest commit's body. If the body looks like a team commit (conventional-commit subject + Closes #N) but lacks a smoke: PASS|FAIL|SKIPPED trailer, the hook exits 2 with a feedback message and the task stays in-progress. Verifier must amend the commit with the correct trailer.
Graceful fallback: if git fails or the commit doesn't match the team-commit shape, the hook exits 0 — we don't block on transient state or unrelated commits.
TeammateIdle → teammate-idle-review.sh
Runs when a teammate is about to go idle. For the implementer only: reads the shared task list (~/.claude/tasks/<team-name>/*.json) and looks for unresolved reviewer change-requests addressed to the implementer. If any are pending, exits 2 with the list of asks. The implementer cannot idle on a task with open review comments.
Reviewer, verifier, and researcher idle freely — they have no pending-work contract analogous to open review comments.
Graceful fallback: if jq is missing or the task files can't be read, exits 0. We don't block legit idles because of a tooling hiccup.
Troubleshooting
- Teammate stops unexpectedly — spawn a replacement of the same role. The shared task list preserves state, and the new teammate picks up where the previous one left off.
- Orphaned
AFK:in-progresslabel — at dispatch start, the lead checks for open issues labeledAFK:in-progresswith no active task in the task list. Stale labels are removed before claiming new work. - Lead shuts down before work is done (known CCT limitation) — if you realize you're about to quit while tasks remain, spawn a replacement teammate for any missing role and resume. Never run "clean up the team" unless the task list is empty.
TaskCompletedhook blocks a task — the verifier committed without asmoke:trailer. Amend the HEAD commit with the correct trailer (git commit --amend) and re-mark the task completed.- tmux not installed — split-pane mode needs tmux or iTerm2. Fall back to in-process mode:
claude --teammate-mode in-process. All coordination still works; you just cycle teammates with Shift+Down instead of clicking panes. - Agent Teams disabled — check
.claude/settings.jsoncontains"CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS": "1"in theenvblock. Without it, the lead cannot spawn teammates —/afk-dispatchwill fail fast.
Related
- Roles — the four subagent definitions
.claude/skills/afk-dispatch/SKILL.md— the full playbookdocs/Harness/self-validation.md— thesmoke:trailer contract the verifier produces- Agent Teams (official docs) — underlying platform feature