In an agentic workflow, the issue queue is the program. The agents are the runtime. Everything that goes wrong in a multi-agent setup, duplicate PRs, confident-but-wrong changes, scope creep, work that never gets picked up, traces back to an issue that was ambiguous, mislabelled, or missing the information an agent needed to finish the job.
This guide is about writing issues that an agent can read once and execute end to end. It assumes the broader setup from Wiring a multi-agent CEO/dev/QA team with Claude Code; here we zoom in on the single most leveraged artifact in that system: the issue.
The principle: an issue is a contract, not a wish
When you write an issue for a human teammate, you can be vague, because they will ask a clarifying question in standup. An agent will not ask. It will pattern-match your vague request to the nearest plausible interpretation and ship it with total confidence. So the issue has to carry everything the agent needs to know, and it has to make the definition of "done" unambiguous.
A good issue for an agent has three jobs:
- State the outcome, not the implementation.
- Make "done" testable.
- Fence off everything the agent must not touch.
Anatomy of an executable issue
Use a fixed structure so both the writer and the agent know where to look. The one I run has four parts.
Title: action-first and scope-bounded
The title is the routing signal. Make it a verb plus a bounded scope.
Good: Add /pricing page with three tiers and a contact CTA
Good: Fix date sort on /blog index (newest first)
Bad: Pricing
Bad: Improve the blog"Improve the blog" is not a task, it is a theme. An agent handed a theme will invent the scope, and the scope it invents will not be the one you wanted.
Goal: the outcome in two or three sentences
State what should be true when the work is done and why it matters, in plain language. This is the agent's north star when an acceptance criterion turns out to be ambiguous. Do not describe the implementation here; describe the result.
Acceptance criteria: a checklist of testable claims
This is the part that does the work. Each item should be something a reviewer (human or agent) can verify as true or false without judgment calls.
## Acceptance criteria
- [ ] `/pricing` route renders three tier cards (Starter, Team, Enterprise)
- [ ] Each card shows name, price, and a feature list
- [ ] A "Talk to us" button on each card links to `/contact`
- [ ] Page has a `<title>`, meta description, and OpenGraph tags via `generateMetadata`
- [ ] `pnpm build` and `pnpm lint` passNotice these are observable facts, not instructions. "Use a grid layout" is an instruction and an over-specification; "three tier cards" is an outcome and lets the agent choose the layout. Reserve instructions for things that genuinely matter (a specific route, a required link target, a build command that must pass).
Constraints and links: the guardrails
This is where you fence the work. List the files in scope, the things explicitly out of scope, and any links the agent needs (a related issue, a design token file, a doc). The single most valuable line you can add is an out-of-scope statement, because it is the only thing standing between a tidy diff and an agent that "helpfully" refactors three unrelated files.
## Constraints / links
- Files: new route under `app/pricing/`; reuse the existing `Card` component
- Do NOT modify the global nav or add a new dependency
- Prices are placeholders; do not wire up Stripe in this issue
- Related: #14 (MDX pipeline), design tokens in `app/globals.css`Labels: exactly one role per issue
In a fan-out dispatch model, the label is what decides which agent picks the issue up. The rule that prevents the most pain is simple: exactly one agent:* label per issue.
If an issue carries two role labels, two agents pick it up, branch from the same commit, and open two competing PRs. If work genuinely spans roles, that is a signal to split it into two issues with a dependency between them, not to double-label one.
agent:dev agent:content agent:design
agent:qa agent:seo agent:opsAdd an optional priority label (priority:high|med|low) so the picking-work step has a deterministic ordering. When an agent is invoked without a specific issue number, it should take the highest-priority open issue for its role that has no existing branch or open PR.
Sizing: one issue, one PR, one reviewable diff
Agents do their best work on issues that map to a single, reviewable pull request. If an acceptance-criteria list is growing past five or six items, or if it spans multiple surfaces (a schema change plus a UI plus copy), split it. Smaller issues mean smaller diffs, which means review actually happens instead of getting rubber-stamped because nobody wants to read four hundred lines.
A useful heuristic: if you cannot imagine reviewing the resulting PR in ten minutes, the issue is too big.
The de-duplication contract
One queue-level discipline saves you from the most common multi-agent failure. Before any agent starts work, it must check for in-flight effort: an existing branch matching the issue, or an open PR that references it. If either exists and is healthy, the agent skips the issue. This belongs in every role agent's prompt, but it is enabled by the queue convention of one branch per issue, named predictably:
agent/<role>/<issue-number>-<slug>Because the branch name is derived from the issue number, any agent can cheaply check "is someone already on #23" before spending a token on the work.
A copy-paste template
Drop this into a GitHub issue template so every issue starts executable:
## Goal
<What should be true when this is done, and why it matters. 2-3 sentences.>
## Acceptance criteria
- [ ] <testable claim>
- [ ] <testable claim>
- [ ] Relevant build/lint/typecheck commands pass
## Constraints / links
- Files: <in-scope paths>
- Do NOT: <out-of-scope work>
- Related: <#issues, docs, design tokens>Label it with exactly one agent:* label and an optional priority, and it is ready for the queue.
What good looks like
You will know your queue is well-structured when agents stop asking for clarification (because the issues answer the questions), when PRs map cleanly one-to-one onto issues, and when your review pass is about whether the change is right rather than figuring out what the change was even trying to do. Getting there is mostly editorial discipline, not tooling. The queue is the part of the system a human still owns outright, and it is the part where careful writing pays back the most.
If you want a second pair of eyes on how your issue queue and agent prompts are structured, reach out.