Agent Team in Claude Code for App Development

Learn how to structure Claude Code agents with orchestration, shared memory, clear roles, and rules for autonomous app development.

Polyana Cunha's avatar
Polyana Cunha
Agent Team in Claude Code for App Development

I wanted a workflow that was easy to describe but difficult to build: one agent acts as a PO and writes issues with me, another implements, another reviews, and another fixes problems as the project keeps evolving. That was the goal when I started structuring agents in Claude Code for Hive, a marketing app for small service businesses such as nail salons, lash studios, and photographers. The mobile app uses React Native + Expo, and the backend is an existing .NET application that we decided to reuse instead of rewriting.

This article is not about the promise. It is about what had to exist to make this work in practice: how the agents communicate (spoiler: they do not), where memory lives between them, what limits each role needs, and what changes when you decide to take the human out of the loop.

What an agent in Claude Code is in practice

An agent in Claude Code (the official name is subagent) is a Markdown file inside .claude/agents/. Its header defines who it is, when to use it, and which tools it can access. The body is the role's manual.

---
name: hive-developer
description: Implements one approved Hive feature on a dedicated branch and opens a PR. Use for Linear issues labeled role:implementation.
tools: Read, Write, Edit, Grep, Glob, Bash
---

# Role — Developer

Implement the approved feature on a dedicated branch and open a PR.

## Required inputs

The orchestrator gives you the Product and Architecture outputs. Do not silently
reinterpret their acceptance criteria. If they are missing or contradictory,
stop and report it — do not guess.

Two properties make all the difference:

  • Isolated context. Each agent starts from scratch. It cannot see the conversation you had earlier or what another agent thought. That is great for focus and terrible if you expected it to “remember.”
  • Tools assigned by role. Hive's reviewer has read-only access (Read, Grep, Glob, Bash). It cannot “tidy up” the code, and that is intentional: the person who reviews should not be the person who fixes.

One detail caught me off guard: the subagent does not talk to you during the task. It receives the request, works until the end, and returns a result. If you want a PO you can discuss issues with through several rounds of back-and-forth, the right place is a command (slash command) that runs in the main session, not a subagent.

Claude Code agents do not talk to one another: someone needs to orchestrate them

The mental image of “one agent handing work to another” is appealing, but that is not how it works. Agents do not exchange messages with one another. The main session coordinates them, acting as an orchestrator: it calls an agent, receives the result, decides what comes next, and passes along whatever is needed.

In Hive, the orchestrator gained two commands:

  • /hive-next: shows which issues are ready to run (with no pending blockers).
  • /hive-issue HIVE-123: loads the issue, identifies the role from its label, and calls the right agent.

Routing is just a table, with no magic involved:

Label Agent
role:planning hive-planning
role:product hive-product
role:architecture hive-architect
role:implementation hive-developer
role:qa hive-qa
role:review hive-reviewer
role:fix hive-fix
role:gate the orchestrator itself evaluates

If an issue has no role label or has two, the orchestrator does not guess: it stops and asks. This is the first rule I would take to any project: routing ambiguity is a bug, not a case to resolve through improvisation.

Linear as shared memory between agents

If no agent can see another agent's session, the information needs to live somewhere outside the chat. In Hive, that place is Linear.

The model is straightforward: one issue = one stage = one execution. Each stage ends by posting a structured comment (STAGE_RESULT:, VALIDATION_RESULT:, REVIEW_RESULT:). The next stage depends on the previous one through the blocked_by relationship, and before running, the orchestrator fetches those comments and gives them to the next agent in full.

This solves three problems at once:

  1. Traceability. You can open a feature and see what the PO decided, what the architecture proposed, what QA rejected, and why.
  2. Resumption. If the session crashes, nothing is lost: the state is in Linear, not in the model's memory.
  3. Independence. QA receives the PO's acceptance criteria, not the developer's opinion about their own code.

The trade-off showed up quickly: in the original design, each feature became six issues (product, architecture, implementation, QA, review, and gate). That is highly traceable and also a lot of noise. We will return to this later.

The roles and why each one needs limits

The Hive team has seven roles. What makes each one useful is not what it does, but what it cannot do:

  • Planning proposes the issue graph and its dependencies. The orchestrator creates the issues in Linear, and only after approval.
  • Product defines behavior and acceptance criteria based on the PRD. It does not write code.
  • Architecture proposes the smallest safe, incremental technical plan. It does not implement it.
  • Development implements on a dedicated branch and opens the PR. If the criteria are contradictory, it stops and reports the problem instead of “interpreting” them.
  • QA has an intentionally uncomfortable mission: try to prove that the implementation does not meet the criteria. It never fixes anything.
  • Review performs an independent senior-level code review. It only reads.
  • Fix addresses only the validated findings from QA and review, on the existing branch.

Above all of them are the project's engineering rules, in a file that agents consult by section: multi-tenancy is mandatory (the tenant is resolved on the server and never comes from the client), secrets must stay out of git, and a failing test must not be deleted or weakened just to make CI pass.

Separating the person who implements from the person who validates is what turns “multiple prompts” into a team. An agent that writes and approves its own code is just an agent with more steps.

Context efficiency: the 2,700-line PRD

Hive's PRD is about 2,700 lines long. In the previous automation, each stage read the entire document, and that was the biggest waste of the process's budget. Worse, it did not help: the agent received an ocean of context to answer a question about a single section.

The solution was simple and became a rule in the project's CLAUDE.md:

  1. There is a prd-index.md with the sections and their line ranges.
  2. The agent reads the index, finds the section, and reads only that portion.
sed -n '2602,2707p' docs/product/hive-product-prd-v6.md

The general lesson: in a multi-agent workflow, context is neither free nor neutral. Each agent should receive the minimum necessary to make a good decision, while the rest should be one query away.

When documentation changes, the backlog rots

This was the most deceptive problem because it does not appear as an error.

Issues are written once and may sit untouched for weeks. Meanwhile, the product changes. In Hive, the mobile scope was reduced to iOS first, but a validation issue still required Android testing. If it ran, QA would reject a correct implementation, the workflow would open a correction cycle, and an agent would spend time “fixing” code that was already right.

Then came a larger change: the Hive Studio plan (teleprompter recording, scene-by-scene uploads, and automatic video editing) became the most up-to-date source of truth for the product, and none of the dozens of open issues mentioned it.

Two practices came out of this:

  • When documentation changes, audit the backlog before running any stage. Renumbered sections, outdated scope, and criteria that contradict newer decisions are the usual suspects.
  • Sometimes, the best option is to restart the backlog. Reviewing dozens of issues when nobody knows where they lead anymore costs more than opening a new project anchored in the current document and keeping the old one as historical record.

From human-in-the-loop to a loop without humans: the decisions that matter

The original design included a human: product questions went to “Human Review,” and only a human could merge. It works, but it does not scale to what I wanted—a workflow that keeps evolving the app on its own and sends me a summary of what was done.

Taking the human out of the loop does not mean deleting a stage. It means replacing human judgment with explicit rules. These are the ones I consider essential:

  • Where the merge happens. If nobody merges, each new feature is built without the previous one and the loop gets stuck in a stack of PRs. The sensible solution is automatic merging into develop after QA and review approve, with master remaining exclusively human-controlled. Autonomy stays on an integration branch, not in production.
  • A product question becomes a recorded assumption. The PO decides, writes the decision in the issue with an assumption label, and continues. You do not approve it beforehand, but you can audit it later.
  • A blocker does not stop the queue. An unavailable simulator, a missing credential, or an unavailable service: the issue is marked as blocked, the reason is recorded once, and the loop moves on to the next one. Retrying an external blocker that has not changed is wasteful.
  • A limit on correction cycles. If QA or review rejects an issue more than twice, it leaves the queue. An infinite correction cycle is the most expensive way to discover that the specification was wrong.
  • The queue renews itself. When there is nothing ready to run, the PO reads the current plan and the code and creates the next few issues. That is what keeps the workflow from stopping without inventing future features on its own.
  • A summary for the human. After each delivery, a short message: what was done, the PR, and the assumptions made by the PO. You leave the critical path without losing control.

And one operational rule: never run two automations against the same backlog. Hive had an earlier automation; with both enabled, they would fight over the status of the same issues.

What I would take to any project

If I were starting a workflow with Claude Code agents in another product today, I would start here:

  • Small agents with clear boundaries. The value lies in what each role cannot do.
  • Handoffs outside the chat. A management tool (Linear, Jira, or GitHub Issues) with structured comments is the team's memory.
  • An explicit orchestrator. Rule-based routing, with a stop whenever there is ambiguity.
  • On-demand context. Indexes and excerpt-based reading, never entire documents by default.
  • A living backlog. When the documentation changes, audit it or start over.
  • Rule-based autonomy. Merging into an integration branch, recorded assumptions, blockers that do not stop the queue, retry limits, and a summary for the product owner.

The result is not a team that does not need you. It is a team in which you stop being the bottleneck and become the person who defines the rules of the game—and for anyone building a product, that is the part that matters most.

Did you enjoy this article?

Share it with your friends and help spread knowledge!