
user.name and user.email configured. Verify with git config --get user.name.claude --version and cross-check the Agent Teams availability in the official documentation for that build.What to do: create the directory skeleton and confirm the toolchain.
Why: every later step reads or writes into these three folders. Creating them first means a missing path shows up now, not in the middle of a run.
How to check:
cd ~/projects/billing-service # replace with your repo
git status --short # expected: no output (clean tree)
mkdir -p roles tasks releases
command -v claude git
Expected output (paths will differ):
/usr/local/bin/claude
/usr/bin/git
An empty git status --short is the important line — it proves no uncommitted work will be mixed into the agent diff.

What to do: create one markdown file per role in roles/, each with a short frontmatter block describing what it reads, what it writes, and when it is done. Do not put a model name in the file.
Why: this is the single design decision behind the "8 model versions, zero role rewrites" result. A role describes *responsibility and output format*; the model is a per-run setting. When a model is replaced, you change one line in the run config, not 12 files.
Example: roles/implementer.md
---
id: implementer
reads: [tasks/TASK-014.md, roles/architect.md, src/**]
writes: [src/**, tests/**]
done_when:
- "npm test exits 0"
- "no file created outside src/ and tests/"
output_format: "unified diff + one-line summary"
---
Write the smallest change that satisfies every acceptance criterion
in the task file. Do not refactor unrelated code. Do not edit RELEASES.md.
The post reports 12 roles but does not publish the list, so use the grouping below as a template and map your own names onto it. Keep the count at 12 or adjust it — what matters is that every role has disjoint write paths.
| Role group | Example role | Reads | Writes |
|---|---|---|---|
| Planning | `architect` | `tasks/*.md` | `plan.md` |
| Implementation | `implementer` | `plan.md`, `src/**` | `src/**`, `tests/**` |
| Verification | `reviewer`, `tester` | `src/**`, `tests/**` | `review.md` |
| Coordination | `lead` | `tasks/*.md`, all role files | routing decisions only |
| Release | `release-manager` | `review.md`, `RELEASES.md` | `RELEASES.md`, git tag |
Two roles writing to the same path is the most common reason a run produces a diff you cannot review. Keep the writes lists disjoint.
Before you hand file access to agents, read AI agent security: protecting your data during automation — the permission scoping there applies directly to src/** write access.
How to check:
ls roles | wc -l
head -6 roles/implementer.md
Expected: 12 on the first line, then the frontmatter block starting with --- and id: implementer. If the count is not 12, ls roles shows which file is missing or duplicated.
What to do: turn one piece of work into a file in tasks/ with three sections — scope, acceptance criteria, and touched paths. Then start a run from the repo root.
Why: in this workflow the human only does two things: sets the task and accepts the result. The task file is therefore the entire interface between you and the 12 agents. Vague criteria produce a diff you have to rewrite by hand.
Example: tasks/TASK-014.md
# TASK-014 — Retry failed billing webhook deliveries
## Scope
- src/webhooks/billing.ts
- tests/webhooks/billing.test.ts
## Acceptance criteria
- [ ] a failed delivery is retried 3 times with exponential backoff
- [ ] retry attempts are logged with the delivery id
- [ ] existing test suite still passes
- [ ] no new runtime dependency added
Start the run. First confirm which non-interactive flags your build exposes:
claude --help | grep -i -E 'print|agent|task'
Expected: one or more lines naming the flags for your version. If nothing matches, open a normal interactive session from the repo root and paste the task file — the rest of this guide is unchanged.
cd ~/projects/billing-service
git switch -c task/TASK-014
claude --print "$(cat tasks/TASK-014.md)" 2>&1 | tee releases/TASK-014.log
How to check:
git status --short
tail -20 releases/TASK-014.log
Expected: only paths listed under Scope appear in git status, and the log ends with the implementer's one-line summary plus a test result. Any file outside the declared scope means a role's writes list is too wide — fix it before the next run.

What to do: run the verification gate, review the diff, then write the release row and tag the commit.
Why: the source workflow logged 44 releases in six months. At that cadence a manual checklist gets skipped within a week, so the gate has to be a command you can run in one line and a checklist you can scan in five seconds.
Example — the gate:
npm test --silent
git diff --stat main
Expected screen output (your test counts will differ):
# tests 42
# pass 42
# fail 0
The git diff --stat line should list only files from the task's Scope section.
Release checklist:
- [ ] `npm test` exits 0
- [ ] `git status --short` shows changes only in declared paths
- [ ] reviewer output contains the acceptance-criteria block, all boxes ticked
- [ ] `RELEASES.md` has a new row: task ID, date, short commit hash
- [ ] `git tag` created and pushed
git commit -am "TASK-014: retry billing webhook deliveries"
git tag -a v1.14.0 -m "TASK-014 billing webhook retry"
git push origin main v1.14.0
If your releases also ship a mobile build, the store submission half of this step is covered in How to Automate App Publishing to App Store and Google Play with AI Agents.
How to check:
git tag --list 'v*' | tail -3
git log --oneline -1
Expected: your new tag on top of the list, and the commit subject starting with TASK-014. If the tag is missing, the git tag line exited non-zero — usually because the message contained a character the shell expanded.
Problem. The CLI is not found after installation
claude: command not foundnvm, asdf, pyenv) that is loaded by an interactive shell only, or the shell config was edited after the current terminal started.command -v claude in the same terminal. If it prints nothing, open a new terminal or run source ~/.zshrc (or ~/.bashrc), then re-check. If it still fails, reinstall following the documentation for your platform.Problem. The run starts but the agents refuse to touch the project
fatal: not a git repository (or any of the parent directories): .gitcd into the repo root and confirm with git rev-parse --show-toplevel, which should print the absolute path of the root. Then re-run from there.Problem. A role file is missing mid-run
Error: ENOENT: no such file or directory, open 'roles/reviewer.md'roles/. This typically appears right after you swap a model and touch the config.ls roles/reviewer.md, then search for stale references with grep -rn "reviewer" roles/ tasks/. Launch every run from the repo root; the model setting belongs in the run command, not in the role file.You now have a 12-role team defined by write-scoped contracts, a task file format that a single run can consume, and a release gate that produces a tag and a RELEASES.md row. The next improvements are tightening the writes lists until git status is predictable, and automating the checklist as a pre-push hook.
How many agents should a Claude Code Agent Team have?
The workflow described here runs 12 roles. That number is a design choice, not a limit — what matters is that each role has a distinct, non-overlapping set of files it may write.
Does the team need one specific model?
No. The roles are deliberately model-agnostic: the model is set per run, not per role file. That is how the same 12 roles survived 8 model versions without being rewritten.
How much does this cost?
The source material does not publish pricing or token figures. Check the official Claude Code pricing documentation for your plan before running long unattended sessions.
Can one developer really ship at this cadence?
In the described setup, yes: 44 releases over six months, with one person setting tasks and accepting results while the agents write the code. The constraint is review discipline, not headcount.