Claude · 11 · Part 6

Advanced Claude Code Workflows

One agent in one session is the baseline. This page covers what changes when the work is bigger than that: changes that span many files, parallel sessions that must not collide, orchestration across many agents, verification that does not rely on trust, CI integration, huge repositories, and tasks that outlive a single context window. The mechanics are exercised on the bookshelf project; the multi-agent features are described from Anthropic's documentation and labelled by maturity.

2
Parallel worktrees run
1
Real merge conflict
3
Maturity levels
Information current as of: 2026-10-30 — Claude Code 2.1.314. Features are labelled documented, research preview or experimental exactly as Anthropic's pages label them.
What was and was not run. No Claude Code session was run for this page. The parallel-worktree, merge, test, verification-script and YAML-parsing outputs are actual: a person (me) played each "agent" by hand so the mechanics are real. Claude Code's own multi-agent features (dynamic workflows, agent teams, background sessions) and claude -p are described from the documentation and were not executed.
00
The Map

Who Holds the Plan?

Anthropic's workflows page draws the key distinction between ways of running a multi-step task: who decides what runs next (Source 1). With subagents, skills and agent teams, Claude orchestrates turn by turn and results land in a context window. With a dynamic workflow, a script holds the plan and only the final answer reaches Claude's context.

Orchestration options, from lightest to heaviest
One sessionyou steer each step · documented SubagentsClaude delegates; summaries return · documented Parallel sessions: worktrees and background sessionsyou run several · worktrees documented, agent view research preview Agent teamspeers message each other · experimental, off by default Dynamic workflowsa script orchestrates many agents · documented, plan-dependent plan held by: you → Claude → peers → a script more agents ≠ better; each step adds tokens and coordination

Reach for the lightest option that fits. Anthropic's agent guidance (Chapter 3) advises starting with the simplest solution and adding complexity only when it measurably helps; the agent-teams page says the same in practice — they add coordination overhead and use significantly more tokens, and for sequential tasks, same-file edits or work with many dependencies a single session or subagents are more effective (Source 2).

01
Workflow 1

Complex Multi-File Changes

For a change that touches several packages — a shared type plus every call site — Anthropic's large-codebase guidance gives two techniques: hand Claude the whole change in one session, so the decisions behind each edit stay consistent, and plan first in plan mode. It adds that Claude writes the plan to a file, and Claude Code re-injects that plan file after each context compaction, so the plan survives where conversation history may not (Source 3).

Prompt pattern: whole change, plan first, check named (bookshelf)
Plan mode. We need to add an "isbn" field to books end to end: entity, DTO, CreateBookRequest (validated, 13 digits), the seed data, and every test that builds a BookDto. Read the code, then write the plan to PLAN.md: files to change in order, the migration/seed impact, and the tests to add. Do not edit anything. After I approve: implement in that order, running ./mvnw -B test after each file group, and stop at the first failure.

Notice the order: files in dependency order, a check after each group, and a stop rule. A multi-file change fails when an early assumption is wrong and later edits compound it; frequent checks turn that into a one-step revert instead of a repository-wide cleanup.

02
Workflow 2

Large-Scale Refactoring

Two ingredients carry over from Chapter 9: an oracle (compare behaviour against the original) and small, checkable steps. What changes at scale is that one conversation cannot hold hundreds of files. This is what dynamic workflows are for: Anthropic's own example prompts include migrating every file in a directory "working on each file in its own isolated copy", and auditing every route handler with adversarial verification of each finding before it is reported (Source 1).

Adapted from the workflows page's migration example · not executed
use a workflow to migrate every class under src/main/java that uses @Autowired field injection to constructor injection, working on each file in its own isolated copy. After each file, run the tests for that class. Report any file that could not be migrated and why.
  • Availability: dynamic workflows are available on all paid plans, with Anthropic API access and on Amazon Bedrock, Google Cloud's Agent Platform and Microsoft Foundry; on Pro you turn them on from the Dynamic workflows row in /config (Source 1).
  • Approve before it runs: Claude Code shows the planned phases and lets you view the raw script first; the exact prompt depends on your permission mode.
  • Try a slice first: the docs advise running on one directory before the whole repository, because one run can use much more than the same task in conversation. A Large workflow warning appears above 25 agents or about 1.5 million projected tokens, and you can set a size guideline (small under 5 agents, medium under 10, large under 50).
  • Hard limits: up to 16 concurrent agents by default, 4,096 items per parallel() or pipeline() call, and 1,000 agents per run.
  • Not interactive mid-run: a run pauses only for agent permission prompts or a usage-limit wait; for sign-off between stages, run each stage as its own workflow.
Scale multiplies a wrong assumption. The decision-table refactor in Chapter 9 was wrong for 1,710 of 3,001 inputs. Run that on 300 files in parallel and you have 300 confident, wrong edits. The oracle check belongs inside every unit of work, not only at the end.
03
Workflow 3

Parallel Task Execution

The simplest, most documented form of parallelism is the one from Chapter 10: one git worktree per session, so edits do not collide. Here is that pattern run for real on bookshelf. Two independent changes — a title-search endpoint and a stats endpoint — each lived in its own worktree and branch, and their test suites ran at the same time.

Two sessions, one repository, two branches, one merge
base a01a832 title-searchedits 3 files + test statsnew files only count-endpointsame lines as search merge: clean7 tests pass count: CONFLICT
Both suites run at the same time, one per worktree · Maven wrapper, Java 21.0.2
$ (cd .claude/worktrees/title-search && ./mvnw -B test) & $ (cd .claude/worktrees/year-filter && ./mvnw -B test) & $ wait
Actual output (summary) · executed 2026-10-30
both finished in 27s (wall clock) title-search exit=0 Tests run: 6, Failures: 0, Errors: 0 BUILD SUCCESS stats exit=0 Tests run: 6, Failures: 0, Errors: 0 BUILD SUCCESS

Then the merge, which is where parallel work succeeds or fails:

$ git merge worktree-title-search $ git merge worktree-year-filter $ ./mvnw -B test
Actual output (excerpt)
Updating a01a832..992cb18 Fast-forward 4 files changed, 42 insertions(+) Merge made by the 'ort' strategy. StatsController.java | 24 +++++++++ StatsControllerTest.java | 28 ++++++++++ 2 files changed, 52 insertions(+) [INFO] Tests run: 7, Failures: 0, Errors: 0, Skipped: 0 [INFO] BUILD SUCCESS

The stats change added only new files, so it merged cleanly with the search change. A third worktree edited the same insertion point in BookController:

Actual output · git merge worktree-count-endpoint
Auto-merging src/main/java/com/example/bookshelf/BookController.java CONFLICT (content): Merge conflict in src/main/java/com/example/bookshelf/BookController.java Automatic merge failed; fix conflicts and then commit the result. <<<<<<< HEAD @GetMapping("/search") public List<BookDto> search(@RequestParam String title) { return service.search(title); ======= @GetMapping("/count") public long count() { return service.findAll().size(); >>>>>>> worktree-count-endpoint

What it shows: two sessions run in half the wall-clock of doing them one after another (27 s for both here, because Maven ran concurrently), and independence is a property of which files each session touches. This is exactly Anthropic's advice for agent teams too: break the work so each teammate owns a different set of files, because two editing the same file leads to overwrites (Source 2). Plan the split before you start the sessions.

04
Workflow 4

Multi-Agent Development and Subagent Orchestration

SubagentsAgent teamsDynamic workflows
Status (as documented)DocumentedExperimental, disabled by defaultDocumented; plan-dependent
Who decides what runs nextClaude, turn by turnThe lead, turn by turn; peers self-coordinateThe script
Where intermediate results liveClaude's contextA shared task list and mailboxesScript variables
ScaleA few per turn (up to 20 concurrent by default)A handful of long-running peers; docs suggest starting with 3–5Dozens to hundreds per run
Repeatable?The worker definitionThe team definitionThe orchestration itself (saveable)

The table combines the workflows page's comparison with the subagent and agent-team pages (Source 1, Source 2, Source 4).

Agent teams: what is documented, and what to treat with care
  • Enable: set CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1. The page's warning says agent teams are experimental, with known limitations around session resumption, task coordination and shutdown.
  • Shape: one session is the team lead; teammates are separate Claude Code sessions with their own context windows, a shared task list and a mailbox. You can message any teammate directly.
  • Best first uses: research and review, not parallel code edits — for example three reviewers on one pull request with distinct lenses (security, performance, test coverage), or several investigators testing competing hypotheses and trying to disprove each other. The page notes sequential investigation suffers from anchoring and that adversarial investigators make the surviving theory more likely to be the root cause.
  • Costs and limits: significantly more tokens than one session; one team per session; no nested teams; no resumption of in-process teammates; teammate permission prompts surface in the lead; teammates inherit the lead's permission mode, so a lead on --dangerously-skip-permissions makes them all bypass. The costs page says agent teams use roughly seven times more tokens than a standard session when teammates run in plan mode (Source 5).
Review prompt from the agent-teams page, adapted · not executed
Spawn three teammates to review the pagination pull request: - one focused on security implications - one checking performance impact (statement counts, N+1) - one validating test coverage Have them each review and report findings with file and line.
A defensive default to remember. When one agent messages another, Claude Code tells the receiver the message came from another Claude session, not from you: a teammate cannot give consent on your behalf, and one that was denied an action cannot relay it to another to get around the check (Source 2). Approval stays with you.
05
Workflow 5

Automated Testing and Verification

More autonomy needs a stricter gate. A useful gate answers two questions mechanically: do the tests pass? and is the change the size we expected? The second matters because an agent that "fixes" a failure by rewriting half the code is a risk the tests alone do not reveal. Here is the bookshelf gate:

scripts/verify.sh
#!/bin/bash # Verification gate for an agent's work: tests must pass and the change must stay within budget. # Usage: scripts/verify.sh [base-ref] [max-files] BASE=${1:-main} MAX_FILES=${2:-20} if ! ./mvnw -B -q test > /tmp/verify-test.log 2>&1; then echo "FAIL: tests failed (see /tmp/verify-test.log)" exit 1 fi echo "PASS: tests" CHANGED=$(git diff --name-only "$BASE"...HEAD | wc -l | tr -d ' ') echo "files changed vs $BASE: $CHANGED (budget $MAX_FILES)" if [ "$CHANGED" -gt "$MAX_FILES" ]; then echo "FAIL: change exceeds budget; split the work or justify it" exit 2 fi echo "PASS: change budget"
$ scripts/verify.sh main 20 $ scripts/verify.sh a01a832 20 $ scripts/verify.sh a01a832 5
Actual output · executed 2026-10-30
PASS: tests files changed vs main: 29 (budget 20) FAIL: change exceeds budget; split the work or justify it (exit 2) PASS: tests files changed vs a01a832: 10 (budget 20) PASS: change budget (exit 0) PASS: tests files changed vs a01a832: 10 (budget 5) FAIL: change exceeds budget; split the work or justify it (exit 2)

Reading it: the whole feature branch is 29 files away from main — a legitimate but large change that a reviewer should see in pieces — while the latest unit of work is 10 files. The right budget depends on the task; the point is that the number is visible and enforced. Three ways to wire a gate in, from weakest to strongest:

WhereHowStrength
In the prompt / CLAUDE.md"Run scripts/verify.sh before you say you are done."A request; Claude usually follows it
A Stop hookExit code 2 sends Claude back to work (Chapter 10); capped at eight consecutive blocksEnforced by Claude Code on every stop
CIThe same script as a required status check on the pull requestEnforced outside the agent entirely
  • Cap the spend and turns of unattended runs: --max-turns and, with -p, --max-budget-usd (the latter appears in this machine's claude --help, Chapter 6).
  • Ask for evidence, not assurance: the command and its output (Chapter 8).
  • Adversarial verification: workflows can have independent agents try to refute each other's findings before reporting; Anthropic describes this as a way to a more trustworthy result than a single pass (Source 1). It lowers false positives; it does not replace a deterministic check.
06
Workflow 6

CI/CD Integration

Two entry points exist, both built on the same engine: the CLI's non-interactive mode, and the Claude Code GitHub Action, which is itself built on the Agent SDK (Source 6, Source 7).

Non-interactive mode: claude -p
  • Basics: claude -p "…" prints the response and exits; it exits 0 on success and non-zero on failure. Output formats: text (default), json (result, session ID, metadata; includes total_cost_usd as a client-side estimate) and stream-json. --json-schema with json output returns validated structured_output.
  • Permissions with nobody watching: in -p a call that needs approval is denied unless something approves it. Use --allowedTools with narrow rules (the docs' example allows only git diff, git log, git status and git commit), --permission-mode dontAsk for locked-down runs, or --permission-prompts none so denied requests do not stall the run.
  • Reproducibility: --bare skips auto-discovery of hooks, skills, subagents, plugins, MCP servers, auto memory and CLAUDE.md, so the same prompt behaves the same on every machine; Anthropic calls it the recommended mode for scripted and SDK calls and says it will become the default for -p in a future release. In bare mode authentication uses ANTHROPIC_API_KEY or an apiKeyHelper, not your subscription login.
  • Piping: stdin is read (capped at 10MB), so git diff main | claude -p "…" works without giving Claude shell permission to read the diff.
From the headless docs, adapted to bookshelf · not executed
$ git diff main | claude -p --bare "review this diff for N+1 queries and missing validation; skip style" \ --output-format json --max-turns 3 | jq -r '.result'
GitHub Actions

A pull-request workflow that runs the tests first and only then asks Claude to review. It follows the structure of the docs' review example (a prompt input puts the action in automation mode; claude_args passes CLI flags). I wrote this file for bookshelf; it was parsed to confirm it is valid YAML with the intended jobs, but it was not run on GitHub.

.github/workflows/claude-review.yml
name: Test and Claude review on: pull_request: types: [opened, synchronize, ready_for_review, reopened] jobs: test: runs-on: ubuntu-latest steps: - uses: actions/checkout@v6 - uses: actions/setup-java@v5 with: distribution: temurin java-version: 21 - run: ./mvnw -B test review: needs: test runs-on: ubuntu-latest permissions: contents: read pull-requests: read issues: read id-token: write steps: - uses: actions/checkout@v6 with: fetch-depth: 1 - uses: anthropics/claude-code-action@v1 with: anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }} prompt: "Review this pull request for correctness and security. Skip style. Report each finding with file, line and a failing scenario." claude_args: "--max-turns 5"
Actual output · PyYAML parse of the file above · executed 2026-10-30
workflow: Test and Claude review jobs: ['test', 'review'] | review needs: test triggers: ['opened', 'synchronize', 'ready_for_review', 'reopened']

(One quirk seen while checking: PyYAML reads the bare key on as the boolean True, a YAML 1.1 behaviour, so the script looked the triggers up under True. GitHub itself treats on as the trigger key.)

Safeguards the docs state for the Action
  • Secrets: store the key as a GitHub secret, never in the repository. The docs warn against committing API keys or OAuth tokens. For a shared organisation secret, use an API key; an OAuth token belongs to whoever ran claude setup-token.
  • Who can trigger it: by default the triggering user needs write access, and bot actors are rejected unless listed in allowed_bots, which keeps bots from triggering Claude in a loop.
  • Cost controls: --max-turns, workflow timeouts and concurrency limits; runs consume GitHub Actions minutes and API tokens.
  • Least privilege: the review job above gets read permissions only; the docs' @claude example grants write because it can push commits. Grant what the job needs.
  • Fork pull requests: on public repositories GitHub withholds secrets from fork-triggered runs, so the review runs only for same-repository branches.
07
Workflow 7

Working with Large Repositories

In a large codebase the defaults tuned for small projects can fill the context window with unrelated instructions and file reads, costing tokens and degrading performance. Anthropic's large-codebase guide scopes Claude to the part you are touching (Source 3):

Scope what loads: a monorepo seen from packages/api
monorepo/ CLAUDE.md.claude/settings.json packages/ api/CLAUDE.md · skills web/ (not loaded) shared/ (read/edit) Started in packages/api/ it… ✔ loads root + api CLAUDE.md✔ skips web/CLAUDE.md✔ reaches shared/ viaadditionalDirectories ✔ denies reads of dist/ build/✔ api-testing skill on demand✔ sparse worktreessparsePaths: api, shared
I want to…Use
Load only the conventions for the code I touchPer-directory CLAUDE.md files (ancestors load at launch; subdirectories on demand)
Skip another team's packageclaudeMdExcludes glob patterns (at any settings scope; arrays merge)
Stop Claude opening build output or vendored codeRead deny rules such as Read(./**/dist/**/*)
Find definitions without scanning filesA code-intelligence plugin (language server)
Check out only some directories in a worktreeworktree.sparsePaths (plus symlinkDirectories to share node_modules)
Edit a sibling package from a subdirectory--add-dir or permissions.additionalDirectories
Share conventions as versioned unitsSkills, then a plugin, as per-directory files stop scaling

Two caveats from the same page matter. Project settings in .claude/settings.json are not inherited from parent directories the way CLAUDE.md files are, so each starting directory needs its own. And Read deny rules cover Claude's built-in file tools and recognised file commands, but a Bash grep -r over a directory containing denied files can still list them, and subprocesses that open files themselves are not covered. For Spring/Maven monorepos the same pattern holds: per-module CLAUDE.md with that module's test command, deny **/target/**.

08
Workflow 8

Long-Running Tasks

A project that spans many context windows hits a problem Anthropic's engineering team describes plainly: each new session starts with no memory of the last; with only a high-level prompt a capable model tends to try to build too much at once, leaving half-finished work, and a later session may see some progress and wrongly declare the project done (Source 8). Their remedy is a harness pattern: an initializer step that creates a feature list, a progress log, a startup script and an initial git commit; then coding sessions that each advance one item and leave the repository ready to merge.

The session loop that survives context resets
Orientfeature listgit log Smoke testis it healthy? One itemimplement+ verify Commitupdateprogress New sessioncontext reset repeat until every feature is passing state lives in files and git, not in the conversation

The article's other findings map to this guide's lessons: agents marked features complete after unit tests or simple API checks without confirming end-to-end behaviour (so verify like a user would); git lets agents revert to working states; and structured JSON status was chosen because models alter it less casually than Markdown. Anthropic also names open questions — whether one general agent beats specialised testing or QA agents is unclear, and the approach was tested mainly on full-stack web development (Source 8). Here is the pattern at bookshelf scale:

feature_list.json (excerpt)
{ "project": "bookshelf", "features": [ { "id": 1, "name": "list books", "status": "passing" }, { "id": 4, "name": "search by title", "status": "passing" }, { "id": 6, "name": "pagination for list", "status": "failing" }, { "id": 7, "name": "delete book", "status": "failing" } ] }
scripts/status.sh — the orientation step for a fresh session
#!/bin/bash jq -r '"features: \([.features[]|select(.status=="passing")]|length)/\(.features|length) passing"' feature_list.json echo "next:" jq -r '.features[]|select(.status!="passing")|" - [\(.id)] \(.name)"' feature_list.json | head -1
Actual output · all seven features in the real file · executed 2026-10-30
features: 5/7 passing next: - [6] pagination for list
  • Only statuses change. Instruct the agent that it may flip status only after the verification command passes, and never edit or delete features.
  • Tools for the unattended case: /loop repeats a prompt in a session; claude --bg starts a background session (agent view is a research preview); a run that hits a claude.ai usage limit can pause and resume itself in an interactive session when autoContinueAtUsageLimit is on, but not in -p, background or Remote Control sessions (Source 1). An expired login stops unattended work.
  • Checkpoints are session-scoped. Git commits are the durable record.
09
Workflow 9

Repeatable Engineering Workflows

A process you run on every branch should not be re-typed. Anthropic's docs offer three levels, each more portable than the last:

LevelWhat you saveWhere
SkillInstructions Claude follows (/verify-build).claude/skills/<name>/SKILL.md
Saved workflowThe orchestration script from a good run: in /workflows, select the run and press s; it becomes /<name> and accepts input through args.claude/workflows/ (shared) or ~/.claude/workflows/ (yours)
PluginSkills, agents, hooks, MCP servers and workflows as one versioned unitA marketplace; plugin workflows are namespaced, e.g. /acme-tools:release-audit

A repeatable workflow also benefits from being run the same way in CI: the GitHub Action can run a skill from your repository (check out the repo first, pass /skill-name as the prompt) or a plugin skill (Source 7). Packaging is the subject of Chapter 12.

10
Common Mistakes

Scaling Up Too Fast

1 · Parallelism without a split. Two sessions on the same file produce conflicts (the real CONFLICT above). Decide file ownership first.
2 · Reaching for agent teams to write code. They are experimental and the docs advise starting with research and review. Single-session or subagent work is often more effective for sequential or same-file tasks.
3 · A workflow on the whole repository first. Try one directory; watch /workflows token use; stop early if the first units look wrong.
4 · No budget on unattended runs. Set --max-turns, --max-budget-usd and timeouts; a stuck agent loop is billed like a working one.
5 · Bypass permissions in CI. Prefer narrow --allowedTools rules or dontAsk, and run in an isolated runner.
6 · Trusting "all features pass". A model can declare a feature done on shallow evidence. Gate status changes on an end-to-end check you control.
7 · State only in the conversation. Anything the next session needs must be in a file and a commit.
11
Summary

Key Takeaways, Exercises and Sources

∑ Advanced workflows — what to remember
  • Ask who holds the plan: you, Claude, peers or a script. Use the lightest option that works.
  • Parallel work is about file ownership. Two worktrees ran at once and merged cleanly; a third touching the same lines conflicted.
  • Scale needs the oracle inside each unit of work, not only at the end.
  • Gate with numbers: tests passing and change size within budget, enforced by a hook or CI.
  • CI integration is the same engine: claude -p and the GitHub Action, with narrow permissions, secrets in secrets, and spend caps.
  • Long tasks live in files and git; sessions are disposable.
  • Know the maturity: agent teams are experimental; agent view is a research preview; workflows are documented but plan-dependent.
Exercises

Exercise 1 Beginner

Create two worktrees from a small repository, make an independent one-file change in each, and merge both. Then make a third change to the same lines as the first and observe the conflict markers.

Learning outcome: see that independence comes from disjoint files.

Exercise 2 Intermediate

Write a verify.sh for your own project that runs the tests and enforces a changed-files budget. Make it fail on purpose twice (a failing test; an over-budget change) and record the exit codes.

Learning outcome: build a mechanical gate you can attach to a Stop hook or CI.

Exercise 3 Advanced

Design a long-running task for a feature set of ten items: write the feature_list.json, a progress file, the orientation script and the rule for when a status may change. Then run two fresh sessions on it and check whether the second one correctly picked up where the first stopped.

Learning outcome: test whether your harness survives a context reset.

Sources (read on 2026-10-30; paraphrased, at most one short quote per source)
  1. Anthropic, Orchestrate subagents at scale with dynamic workflows — comparison table, availability, approval, saving, limits, cost, size guideline, usage-limit behaviour.
  2. Anthropic, Orchestrate teams of Claude Code sessions — experimental status, architecture, use cases, limitations, permissions, message handling.
  3. Anthropic, Monorepos and large codebases — CLAUDE.md layering, excludes, deny rules, code intelligence, sparse worktrees, additional directories, cross-package changes.
  4. Anthropic, Subagents — concurrency limit and nesting (also Chapter 10).
  5. Anthropic, Manage costs — agent-team token cost; enablement variable.
  6. Anthropic, Run Claude Code programmatically — -p, output formats, --bare, permissions in non-interactive runs, piping.
  7. Anthropic, Claude Code GitHub Actions — setup, modes, who can trigger, example workflows, secrets, costs.
  8. Anthropic, Effective harnesses for long-running agents — initializer/coding-agent pattern, feature lists, progress files, testing, limitations. Engineering article; not product documentation.

Executed on this machine, 2026-10-30: git worktree/merge, two concurrent ./mvnw -B test runs and the merged suite (Spring Boot 4.1.2, OpenJDK 21.0.2, Maven 3.10.0 wrapper), the verification script, jq status script, and a PyYAML parse of the workflow. Not executed: claude -p, dynamic workflows, agent teams, background sessions, GitHub Actions runs. The two "agents" were a person making edits by hand.